From 705c4cb50eea66585cc95c7314001fce9dd197cd Mon Sep 17 00:00:00 2001 From: Stefan Suhren Date: Tue, 5 May 2015 19:34:39 +0200 Subject: Initial commit --- .buildpath | 5 + .project | 34 + .settings/.jsdtscope | 16 + .settings/org.eclipse.php.core.prefs | 2 + .../org.eclipse.wst.common.project.facet.core.xml | 7 + .../org.eclipse.wst.jsdt.ui.superType.container | 1 + .settings/org.eclipse.wst.jsdt.ui.superType.name | 1 + catalog.sql | 170 ++ categories.php | 35 + composer.json | 8 + composer.lock | 513 +++++ config/propel.yaml | 46 + contact.html | 23 + generated-classes/Base/Category.php | 1816 ++++++++++++++++ generated-classes/Base/CategoryQuery.php | 507 +++++ generated-classes/Base/Product.php | 1996 ++++++++++++++++++ generated-classes/Base/ProductCategory.php | 1328 ++++++++++++ generated-classes/Base/ProductCategoryQuery.php | 571 +++++ generated-classes/Base/ProductQuery.php | 645 ++++++ generated-classes/Base/User.php | 1174 +++++++++++ generated-classes/Base/UserQuery.php | 398 ++++ generated-classes/Category.php | 18 + generated-classes/CategoryQuery.php | 18 + generated-classes/Map/CategoryTableMap.php | 424 ++++ generated-classes/Map/ProductCategoryTableMap.php | 491 +++++ generated-classes/Map/ProductTableMap.php | 448 ++++ generated-classes/Map/UserTableMap.php | 412 ++++ generated-classes/Product.php | 18 + generated-classes/ProductCategory.php | 18 + generated-classes/ProductCategoryQuery.php | 18 + generated-classes/ProductQuery.php | 18 + generated-classes/User.php | 18 + generated-classes/UserQuery.php | 18 + generated-conf/config.php | 29 + index.html | 24 + login.html | 41 + productdetails.php | 75 + products.php | 45 + schema.xml | 46 + styles/style.css | 86 + vendor.inc.php | 8 + vendor/autoload.php | 7 + vendor/bin/propel | 4 + vendor/composer/ClassLoader.php | 413 ++++ vendor/composer/autoload_classmap.php | 29 + vendor/composer/autoload_namespaces.php | 18 + vendor/composer/autoload_psr4.php | 9 + vendor/composer/autoload_real.php | 50 + vendor/composer/installed.json | 513 +++++ vendor/propel/propel | 1 + vendor/psr/log/.gitignore | 1 + vendor/psr/log/LICENSE | 19 + vendor/psr/log/Psr/Log/AbstractLogger.php | 120 ++ .../psr/log/Psr/Log/InvalidArgumentException.php | 7 + vendor/psr/log/Psr/Log/LogLevel.php | 18 + vendor/psr/log/Psr/Log/LoggerAwareInterface.php | 17 + vendor/psr/log/Psr/Log/LoggerAwareTrait.php | 22 + vendor/psr/log/Psr/Log/LoggerInterface.php | 114 + vendor/psr/log/Psr/Log/LoggerTrait.php | 131 ++ vendor/psr/log/Psr/Log/NullLogger.php | 27 + .../psr/log/Psr/Log/Test/LoggerInterfaceTest.php | 116 + vendor/psr/log/README.md | 45 + vendor/psr/log/composer.json | 17 + .../config/Symfony/Component/Config/.gitignore | 3 + .../config/Symfony/Component/Config/CHANGELOG.md | 21 + .../Symfony/Component/Config/ConfigCache.php | 126 ++ .../Component/Config/Definition/ArrayNode.php | 393 ++++ .../Component/Config/Definition/BaseNode.php | 360 ++++ .../Component/Config/Definition/BooleanNode.php | 42 + .../Definition/Builder/ArrayNodeDefinition.php | 489 +++++ .../Definition/Builder/BooleanNodeDefinition.php | 42 + .../Definition/Builder/EnumNodeDefinition.php | 58 + .../Config/Definition/Builder/ExprBuilder.php | 238 +++ .../Definition/Builder/FloatNodeDefinition.php | 32 + .../Definition/Builder/IntegerNodeDefinition.php | 32 + .../Config/Definition/Builder/MergeBuilder.php | 72 + .../Config/Definition/Builder/NodeBuilder.php | 245 +++ .../Config/Definition/Builder/NodeDefinition.php | 343 +++ .../Definition/Builder/NodeParentInterface.php | 21 + .../Definition/Builder/NormalizationBuilder.php | 67 + .../Definition/Builder/NumericNodeDefinition.php | 61 + .../Builder/ParentNodeDefinitionInterface.php | 26 + .../Definition/Builder/ScalarNodeDefinition.php | 32 + .../Config/Definition/Builder/TreeBuilder.php | 63 + .../Definition/Builder/ValidationBuilder.php | 51 + .../Definition/Builder/VariableNodeDefinition.php | 64 + .../Config/Definition/ConfigurationInterface.php | 27 + .../Definition/Dumper/XmlReferenceDumper.php | 300 +++ .../Definition/Dumper/YamlReferenceDumper.php | 198 ++ .../Component/Config/Definition/EnumNode.php | 58 + .../Definition/Exception/DuplicateKeyException.php | 22 + .../Config/Definition/Exception/Exception.php | 21 + .../Exception/ForbiddenOverwriteException.php | 22 + .../Exception/InvalidConfigurationException.php | 49 + .../Exception/InvalidDefinitionException.php | 21 + .../Definition/Exception/InvalidTypeException.php | 21 + .../Definition/Exception/UnsetKeyException.php | 22 + .../Component/Config/Definition/FloatNode.php | 43 + .../Component/Config/Definition/IntegerNode.php | 38 + .../Component/Config/Definition/NodeInterface.php | 88 + .../Component/Config/Definition/NumericNode.php | 55 + .../Component/Config/Definition/Processor.php | 97 + .../Config/Definition/PrototypeNodeInterface.php | 27 + .../Config/Definition/PrototypedArrayNode.php | 331 +++ .../Config/Definition/ReferenceDumper.php | 21 + .../Component/Config/Definition/ScalarNode.php | 49 + .../Component/Config/Definition/VariableNode.php | 119 ++ .../FileLoaderImportCircularReferenceException.php | 27 + .../Config/Exception/FileLoaderLoadException.php | 100 + .../Symfony/Component/Config/FileLocator.php | 95 + .../Component/Config/FileLocatorInterface.php | 31 + .../config/Symfony/Component/Config/LICENSE | 19 + .../Component/Config/Loader/DelegatingLoader.php | 55 + .../Symfony/Component/Config/Loader/FileLoader.php | 124 ++ .../Symfony/Component/Config/Loader/Loader.php | 78 + .../Component/Config/Loader/LoaderInterface.php | 54 + .../Component/Config/Loader/LoaderResolver.php | 75 + .../Config/Loader/LoaderResolverInterface.php | 30 + .../config/Symfony/Component/Config/README.md | 17 + .../Config/Resource/DirectoryResource.php | 99 + .../Component/Config/Resource/FileResource.php | 75 + .../Config/Resource/ResourceInterface.php | 43 + .../Component/Config/Tests/ConfigCacheTest.php | 138 ++ .../Config/Tests/Definition/ArrayNodeTest.php | 160 ++ .../Config/Tests/Definition/BooleanNodeTest.php | 60 + .../Definition/Builder/ArrayNodeDefinitionTest.php | 207 ++ .../Definition/Builder/EnumNodeDefinitionTest.php | 46 + .../Tests/Definition/Builder/ExprBuilderTest.php | 215 ++ .../Tests/Definition/Builder/NodeBuilderTest.php | 94 + .../Builder/NumericNodeDefinitionTest.php | 93 + .../Tests/Definition/Builder/TreeBuilderTest.php | 126 ++ .../Definition/Dumper/XmlReferenceDumperTest.php | 80 + .../Definition/Dumper/YamlReferenceDumperTest.php | 67 + .../Config/Tests/Definition/EnumNodeTest.php | 41 + .../Config/Tests/Definition/FinalizationTest.php | 73 + .../Config/Tests/Definition/FloatNodeTest.php | 64 + .../Config/Tests/Definition/IntegerNodeTest.php | 61 + .../Config/Tests/Definition/MergeTest.php | 195 ++ .../Config/Tests/Definition/NormalizationTest.php | 229 ++ .../Tests/Definition/PrototypedArrayNodeTest.php | 180 ++ .../Config/Tests/Definition/ScalarNodeTest.php | 79 + .../Exception/FileLoaderLoadExceptionTest.php | 83 + .../Component/Config/Tests/FileLocatorTest.php | 119 ++ .../Component/Config/Tests/Fixtures/Again/foo.xml | 0 .../Tests/Fixtures/Builder/BarNodeDefinition.php | 21 + .../Config/Tests/Fixtures/Builder/NodeBuilder.php | 34 + .../Fixtures/Builder/VariableNodeDefinition.php | 18 + .../Configuration/ExampleConfiguration.php | 71 + .../Config/Tests/Fixtures/Util/document_type.xml | 3 + .../Config/Tests/Fixtures/Util/invalid.xml | 2 + .../Config/Tests/Fixtures/Util/invalid_schema.xml | 2 + .../Config/Tests/Fixtures/Util/schema.xsd | 9 + .../Component/Config/Tests/Fixtures/Util/valid.xml | 3 + .../Component/Config/Tests/Fixtures/foo.xml | 0 .../Config/Tests/Loader/DelegatingLoaderTest.php | 83 + .../Config/Tests/Loader/FileLoaderTest.php | 106 + .../Config/Tests/Loader/LoaderResolverTest.php | 56 + .../Component/Config/Tests/Loader/LoaderTest.php | 117 ++ .../Tests/Resource/DirectoryResourceTest.php | 152 ++ .../Config/Tests/Resource/FileResourceTest.php | 61 + .../Component/Config/Tests/Util/XmlUtilsTest.php | 197 ++ .../Symfony/Component/Config/Util/XmlUtils.php | 238 +++ .../config/Symfony/Component/Config/composer.json | 35 + .../Symfony/Component/Config/phpunit.xml.dist | 28 + .../console/Symfony/Component/Console/.gitignore | 3 + .../Symfony/Component/Console/Application.php | 1173 +++++++++++ .../console/Symfony/Component/Console/CHANGELOG.md | 62 + .../Symfony/Component/Console/Command/Command.php | 661 ++++++ .../Component/Console/Command/HelpCommand.php | 91 + .../Component/Console/Command/ListCommand.php | 95 + .../Symfony/Component/Console/ConsoleEvents.php | 61 + .../Console/Descriptor/ApplicationDescription.php | 155 ++ .../Component/Console/Descriptor/Descriptor.php | 121 ++ .../Console/Descriptor/DescriptorInterface.php | 31 + .../Console/Descriptor/JsonDescriptor.php | 167 ++ .../Console/Descriptor/MarkdownDescriptor.php | 141 ++ .../Console/Descriptor/TextDescriptor.php | 255 +++ .../Component/Console/Descriptor/XmlDescriptor.php | 266 +++ .../Console/Event/ConsoleCommandEvent.php | 62 + .../Component/Console/Event/ConsoleEvent.php | 67 + .../Console/Event/ConsoleExceptionEvent.php | 67 + .../Console/Event/ConsoleTerminateEvent.php | 58 + .../Console/Formatter/OutputFormatter.php | 241 +++ .../Console/Formatter/OutputFormatterInterface.php | 83 + .../Console/Formatter/OutputFormatterStyle.php | 227 ++ .../Formatter/OutputFormatterStyleInterface.php | 72 + .../Formatter/OutputFormatterStyleStack.php | 121 ++ .../Console/Helper/DebugFormatterHelper.php | 127 ++ .../Component/Console/Helper/DescriptorHelper.php | 96 + .../Component/Console/Helper/DialogHelper.php | 476 +++++ .../Component/Console/Helper/FormatterHelper.php | 82 + .../Symfony/Component/Console/Helper/Helper.php | 121 ++ .../Component/Console/Helper/HelperInterface.php | 49 + .../Symfony/Component/Console/Helper/HelperSet.php | 108 + .../Component/Console/Helper/InputAwareHelper.php | 33 + .../Component/Console/Helper/ProcessHelper.php | 142 ++ .../Component/Console/Helper/ProgressBar.php | 611 ++++++ .../Component/Console/Helper/ProgressHelper.php | 457 ++++ .../Component/Console/Helper/QuestionHelper.php | 418 ++++ .../Symfony/Component/Console/Helper/Table.php | 410 ++++ .../Component/Console/Helper/TableHelper.php | 263 +++ .../Component/Console/Helper/TableSeparator.php | 21 + .../Component/Console/Helper/TableStyle.php | 251 +++ .../Symfony/Component/Console/Input/ArgvInput.php | 353 ++++ .../Symfony/Component/Console/Input/ArrayInput.php | 211 ++ .../Symfony/Component/Console/Input/Input.php | 226 ++ .../Component/Console/Input/InputArgument.php | 132 ++ .../Console/Input/InputAwareInterface.php | 28 + .../Component/Console/Input/InputDefinition.php | 453 ++++ .../Component/Console/Input/InputInterface.php | 152 ++ .../Component/Console/Input/InputOption.php | 213 ++ .../Component/Console/Input/StringInput.php | 83 + .../console/Symfony/Component/Console/LICENSE | 19 + .../Component/Console/Logger/ConsoleLogger.php | 118 ++ .../Component/Console/Output/BufferedOutput.php | 48 + .../Component/Console/Output/ConsoleOutput.php | 113 + .../Console/Output/ConsoleOutputInterface.php | 35 + .../Component/Console/Output/NullOutput.php | 113 + .../Symfony/Component/Console/Output/Output.php | 165 ++ .../Component/Console/Output/OutputInterface.php | 113 + .../Component/Console/Output/StreamOutput.php | 103 + .../Component/Console/Question/ChoiceQuestion.php | 150 ++ .../Console/Question/ConfirmationQuestion.php | 55 + .../Component/Console/Question/Question.php | 238 +++ .../console/Symfony/Component/Console/README.md | 67 + .../Console/Resources/bin/hiddeninput.exe | Bin 0 -> 9216 bytes .../console/Symfony/Component/Console/Shell.php | 228 ++ .../Component/Console/Tester/ApplicationTester.php | 128 ++ .../Component/Console/Tester/CommandTester.php | 132 ++ .../Component/Console/Tests/ApplicationTest.php | 1060 ++++++++++ .../Console/Tests/Command/CommandTest.php | 348 +++ .../Console/Tests/Command/HelpCommandTest.php | 64 + .../Console/Tests/Command/ListCommandTest.php | 64 + .../Tests/Descriptor/AbstractDescriptorTest.php | 105 + .../Tests/Descriptor/JsonDescriptorTest.php | 27 + .../Tests/Descriptor/MarkdownDescriptorTest.php | 27 + .../Console/Tests/Descriptor/ObjectsProvider.php | 74 + .../Tests/Descriptor/TextDescriptorTest.php | 27 + .../Console/Tests/Descriptor/XmlDescriptorTest.php | 27 + .../Console/Tests/Fixtures/BarBucCommand.php | 11 + .../Tests/Fixtures/DescriptorApplication1.php | 18 + .../Tests/Fixtures/DescriptorApplication2.php | 24 + .../Console/Tests/Fixtures/DescriptorCommand1.php | 27 + .../Console/Tests/Fixtures/DescriptorCommand2.php | 30 + .../Console/Tests/Fixtures/DummyOutput.php | 36 + .../Console/Tests/Fixtures/Foo1Command.php | 26 + .../Console/Tests/Fixtures/Foo2Command.php | 21 + .../Console/Tests/Fixtures/Foo3Command.php | 29 + .../Console/Tests/Fixtures/Foo4Command.php | 11 + .../Console/Tests/Fixtures/Foo5Command.php | 10 + .../Console/Tests/Fixtures/FooCommand.php | 33 + .../Tests/Fixtures/FooSubnamespaced1Command.php | 26 + .../Tests/Fixtures/FooSubnamespaced2Command.php | 26 + .../Console/Tests/Fixtures/FoobarCommand.php | 25 + .../Console/Tests/Fixtures/TestCommand.php | 28 + .../Console/Tests/Fixtures/application_1.json | 1 + .../Console/Tests/Fixtures/application_1.md | 199 ++ .../Console/Tests/Fixtures/application_1.txt | 17 + .../Console/Tests/Fixtures/application_1.xml | 108 + .../Console/Tests/Fixtures/application_2.json | 1 + .../Console/Tests/Fixtures/application_2.md | 388 ++++ .../Console/Tests/Fixtures/application_2.txt | 22 + .../Console/Tests/Fixtures/application_2.xml | 185 ++ .../Console/Tests/Fixtures/application_astext1.txt | 20 + .../Console/Tests/Fixtures/application_astext2.txt | 16 + .../Console/Tests/Fixtures/application_asxml1.txt | 144 ++ .../Console/Tests/Fixtures/application_asxml2.txt | 37 + .../Console/Tests/Fixtures/application_gethelp.txt | 1 + .../Fixtures/application_renderexception1.txt | 8 + .../Fixtures/application_renderexception2.txt | 11 + .../Fixtures/application_renderexception3.txt | 27 + .../application_renderexception3decorated.txt | 27 + .../Fixtures/application_renderexception4.txt | 9 + .../application_renderexception_doublewidth1.txt | 11 + ...ation_renderexception_doublewidth1decorated.txt | 11 + .../application_renderexception_doublewidth2.txt | 12 + .../Console/Tests/Fixtures/application_run1.txt | 17 + .../Console/Tests/Fixtures/application_run2.txt | 29 + .../Console/Tests/Fixtures/application_run3.txt | 27 + .../Console/Tests/Fixtures/application_run4.txt | 1 + .../Console/Tests/Fixtures/command_1.json | 1 + .../Component/Console/Tests/Fixtures/command_1.md | 8 + .../Component/Console/Tests/Fixtures/command_1.txt | 7 + .../Component/Console/Tests/Fixtures/command_1.xml | 12 + .../Console/Tests/Fixtures/command_2.json | 1 + .../Component/Console/Tests/Fixtures/command_2.md | 30 + .../Component/Console/Tests/Fixtures/command_2.txt | 11 + .../Component/Console/Tests/Fixtures/command_2.xml | 18 + .../Console/Tests/Fixtures/command_astext.txt | 18 + .../Console/Tests/Fixtures/command_asxml.txt | 38 + .../Console/Tests/Fixtures/definition_astext.txt | 11 + .../Console/Tests/Fixtures/definition_asxml.txt | 39 + .../Console/Tests/Fixtures/input_argument_1.json | 1 + .../Console/Tests/Fixtures/input_argument_1.md | 7 + .../Console/Tests/Fixtures/input_argument_1.txt | 1 + .../Console/Tests/Fixtures/input_argument_1.xml | 5 + .../Console/Tests/Fixtures/input_argument_2.json | 1 + .../Console/Tests/Fixtures/input_argument_2.md | 7 + .../Console/Tests/Fixtures/input_argument_2.txt | 1 + .../Console/Tests/Fixtures/input_argument_2.xml | 5 + .../Console/Tests/Fixtures/input_argument_3.json | 1 + .../Console/Tests/Fixtures/input_argument_3.md | 7 + .../Console/Tests/Fixtures/input_argument_3.txt | 1 + .../Console/Tests/Fixtures/input_argument_3.xml | 7 + .../Console/Tests/Fixtures/input_definition_1.json | 1 + .../Console/Tests/Fixtures/input_definition_1.md | 0 .../Console/Tests/Fixtures/input_definition_1.txt | 0 .../Console/Tests/Fixtures/input_definition_1.xml | 5 + .../Console/Tests/Fixtures/input_definition_2.json | 1 + .../Console/Tests/Fixtures/input_definition_2.md | 9 + .../Console/Tests/Fixtures/input_definition_2.txt | 2 + .../Console/Tests/Fixtures/input_definition_2.xml | 10 + .../Console/Tests/Fixtures/input_definition_3.json | 1 + .../Console/Tests/Fixtures/input_definition_3.md | 11 + .../Console/Tests/Fixtures/input_definition_3.txt | 2 + .../Console/Tests/Fixtures/input_definition_3.xml | 9 + .../Console/Tests/Fixtures/input_definition_4.json | 1 + .../Console/Tests/Fixtures/input_definition_4.md | 21 + .../Console/Tests/Fixtures/input_definition_4.txt | 5 + .../Console/Tests/Fixtures/input_definition_4.xml | 14 + .../Console/Tests/Fixtures/input_option_1.json | 1 + .../Console/Tests/Fixtures/input_option_1.md | 9 + .../Console/Tests/Fixtures/input_option_1.txt | 1 + .../Console/Tests/Fixtures/input_option_1.xml | 4 + .../Console/Tests/Fixtures/input_option_2.json | 1 + .../Console/Tests/Fixtures/input_option_2.md | 9 + .../Console/Tests/Fixtures/input_option_2.txt | 1 + .../Console/Tests/Fixtures/input_option_2.xml | 7 + .../Console/Tests/Fixtures/input_option_3.json | 1 + .../Console/Tests/Fixtures/input_option_3.md | 9 + .../Console/Tests/Fixtures/input_option_3.txt | 1 + .../Console/Tests/Fixtures/input_option_3.xml | 5 + .../Console/Tests/Fixtures/input_option_4.json | 1 + .../Console/Tests/Fixtures/input_option_4.md | 9 + .../Console/Tests/Fixtures/input_option_4.txt | 1 + .../Console/Tests/Fixtures/input_option_4.xml | 5 + .../Formatter/OutputFormatterStyleStackTest.php | 70 + .../Tests/Formatter/OutputFormatterStyleTest.php | 93 + .../Tests/Formatter/OutputFormatterTest.php | 257 +++ .../Console/Tests/Helper/FormatterHelperTest.php | 99 + .../Console/Tests/Helper/HelperSetTest.php | 153 ++ .../Tests/Helper/LegacyDialogHelperTest.php | 200 ++ .../Tests/Helper/LegacyProgressHelperTest.php | 232 ++ .../Console/Tests/Helper/LegacyTableHelperTest.php | 325 +++ .../Console/Tests/Helper/ProcessHelperTest.php | 118 ++ .../Console/Tests/Helper/ProgressBarTest.php | 598 ++++++ .../Console/Tests/Helper/QuestionHelperTest.php | 238 +++ .../Component/Console/Tests/Helper/TableTest.php | 357 ++++ .../Console/Tests/Input/ArgvInputTest.php | 317 +++ .../Console/Tests/Input/ArrayInputTest.php | 138 ++ .../Console/Tests/Input/InputArgumentTest.php | 111 + .../Console/Tests/Input/InputDefinitionTest.php | 430 ++++ .../Console/Tests/Input/InputOptionTest.php | 204 ++ .../Component/Console/Tests/Input/InputTest.php | 121 ++ .../Console/Tests/Input/StringInputTest.php | 101 + .../Console/Tests/Logger/ConsoleLoggerTest.php | 58 + .../Console/Tests/Output/ConsoleOutputTest.php | 25 + .../Console/Tests/Output/NullOutputTest.php | 39 + .../Component/Console/Tests/Output/OutputTest.php | 156 ++ .../Console/Tests/Output/StreamOutputTest.php | 60 + .../Console/Tests/Tester/ApplicationTesterTest.php | 69 + .../Console/Tests/Tester/CommandTesterTest.php | 84 + .../Symfony/Component/Console/composer.json | 42 + .../Symfony/Component/Console/phpunit.xml.dist | 28 + .../Symfony/Component/Filesystem/.gitignore | 3 + .../Symfony/Component/Filesystem/CHANGELOG.md | 28 + .../Filesystem/Exception/ExceptionInterface.php | 23 + .../Filesystem/Exception/FileNotFoundException.php | 34 + .../Component/Filesystem/Exception/IOException.php | 41 + .../Filesystem/Exception/IOExceptionInterface.php | 27 + .../Symfony/Component/Filesystem/Filesystem.php | 497 +++++ .../Symfony/Component/Filesystem/LICENSE | 19 + .../Symfony/Component/Filesystem/LockHandler.php | 111 + .../Symfony/Component/Filesystem/README.md | 47 + .../Component/Filesystem/Tests/ExceptionTest.php | 46 + .../Component/Filesystem/Tests/FilesystemTest.php | 998 +++++++++ .../Filesystem/Tests/FilesystemTestCase.php | 131 ++ .../Component/Filesystem/Tests/LockHandlerTest.php | 85 + .../Symfony/Component/Filesystem/composer.json | 34 + .../Symfony/Component/Filesystem/phpunit.xml.dist | 26 + .../finder/Symfony/Component/Finder/.gitignore | 3 + .../Component/Finder/Adapter/AbstractAdapter.php | 236 +++ .../Finder/Adapter/AbstractFindAdapter.php | 327 +++ .../Component/Finder/Adapter/AdapterInterface.php | 144 ++ .../Component/Finder/Adapter/BsdFindAdapter.php | 103 + .../Component/Finder/Adapter/GnuFindAdapter.php | 104 + .../Component/Finder/Adapter/PhpAdapter.php | 98 + .../finder/Symfony/Component/Finder/CHANGELOG.md | 34 + .../Component/Finder/Comparator/Comparator.php | 98 + .../Component/Finder/Comparator/DateComparator.php | 53 + .../Finder/Comparator/NumberComparator.php | 81 + .../Finder/Exception/AccessDeniedException.php | 19 + .../Finder/Exception/AdapterFailureException.php | 46 + .../Finder/Exception/ExceptionInterface.php | 23 + .../Exception/OperationNotPermitedException.php | 19 + .../Exception/ShellCommandFailureException.php | 45 + .../Component/Finder/Expression/Expression.php | 146 ++ .../Symfony/Component/Finder/Expression/Glob.php | 157 ++ .../Symfony/Component/Finder/Expression/Regex.php | 321 +++ .../Component/Finder/Expression/ValueInterface.php | 60 + .../finder/Symfony/Component/Finder/Finder.php | 840 ++++++++ .../finder/Symfony/Component/Finder/Glob.php | 103 + .../Finder/Iterator/CustomFilterIterator.php | 63 + .../Finder/Iterator/DateRangeFilterIterator.php | 60 + .../Finder/Iterator/DepthRangeFilterIterator.php | 47 + .../Iterator/ExcludeDirectoryFilterIterator.php | 55 + .../Finder/Iterator/FilePathsIterator.php | 131 ++ .../Finder/Iterator/FileTypeFilterIterator.php | 55 + .../Finder/Iterator/FilecontentFilterIterator.php | 76 + .../Finder/Iterator/FilenameFilterIterator.php | 67 + .../Component/Finder/Iterator/FilterIterator.php | 49 + .../Finder/Iterator/MultiplePcreFilterIterator.php | 66 + .../Finder/Iterator/PathFilterIterator.php | 74 + .../Finder/Iterator/RecursiveDirectoryIterator.php | 126 ++ .../Finder/Iterator/SizeRangeFilterIterator.php | 59 + .../Component/Finder/Iterator/SortableIterator.php | 82 + .../finder/Symfony/Component/Finder/LICENSE | 19 + .../finder/Symfony/Component/Finder/README.md | 53 + .../Symfony/Component/Finder/Shell/Command.php | 294 +++ .../Symfony/Component/Finder/Shell/Shell.php | 97 + .../Symfony/Component/Finder/SplFileInfo.php | 77 + .../Finder/Tests/Comparator/ComparatorTest.php | 64 + .../Finder/Tests/Comparator/DateComparatorTest.php | 63 + .../Tests/Comparator/NumberComparatorTest.php | 107 + .../Finder/Tests/Expression/ExpressionTest.php | 68 + .../Component/Finder/Tests/Expression/GlobTest.php | 47 + .../Finder/Tests/Expression/RegexTest.php | 143 ++ .../Finder/Tests/FakeAdapter/DummyAdapter.php | 57 + .../Finder/Tests/FakeAdapter/FailingAdapter.php | 45 + .../Finder/Tests/FakeAdapter/NamedAdapter.php | 57 + .../Tests/FakeAdapter/UnsupportedAdapter.php | 44 + .../Symfony/Component/Finder/Tests/FinderTest.php | 869 ++++++++ .../Component/Finder/Tests/Fixtures/A/B/C/abc.dat | 0 .../Component/Finder/Tests/Fixtures/A/B/ab.dat | 0 .../Component/Finder/Tests/Fixtures/A/a.dat | 0 .../Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy | 0 .../Finder/Tests/Fixtures/copy/A/B/ab.dat.copy | 0 .../Finder/Tests/Fixtures/copy/A/a.dat.copy | 0 .../Component/Finder/Tests/Fixtures/dolor.txt | 2 + .../Component/Finder/Tests/Fixtures/ipsum.txt | 2 + .../Component/Finder/Tests/Fixtures/lorem.txt | 2 + .../Symfony/Component/Finder/Tests/Fixtures/one/a | 0 .../Component/Finder/Tests/Fixtures/one/b/c.neon | 0 .../Component/Finder/Tests/Fixtures/one/b/d.neon | 0 .../Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat | 0 .../Finder/Tests/Fixtures/with space/foo.txt | 0 .../Tests/Iterator/CustomFilterIteratorTest.php | 46 + .../Tests/Iterator/DateRangeFilterIteratorTest.php | 72 + .../Iterator/DepthRangeFilterIteratorTest.php | 80 + .../ExcludeDirectoryFilterIteratorTest.php | 64 + .../Tests/Iterator/FilePathsIteratorTest.php | 69 + .../Tests/Iterator/FileTypeFilterIteratorTest.php | 72 + .../Iterator/FilecontentFilterIteratorTest.php | 86 + .../Tests/Iterator/FilenameFilterIteratorTest.php | 54 + .../Finder/Tests/Iterator/FilterIteratorTest.php | 50 + .../Component/Finder/Tests/Iterator/Iterator.php | 55 + .../Finder/Tests/Iterator/IteratorTestCase.php | 98 + .../Finder/Tests/Iterator/MockFileListIterator.php | 21 + .../Finder/Tests/Iterator/MockSplFileInfo.php | 134 ++ .../Iterator/MultiplePcreFilterIteratorTest.php | 67 + .../Tests/Iterator/PathFilterIteratorTest.php | 83 + .../Finder/Tests/Iterator/RealIteratorTestCase.php | 109 + .../Iterator/RecursiveDirectoryIteratorTest.php | 83 + .../Tests/Iterator/SizeRangeFilterIteratorTest.php | 68 + .../Finder/Tests/Iterator/SortableIteratorTest.php | 169 ++ .../finder/Symfony/Component/Finder/composer.json | 34 + .../Symfony/Component/Finder/phpunit.xml.dist | 27 + .../Symfony/Component/Translation/.gitignore | 3 + .../Symfony/Component/Translation/CHANGELOG.md | 42 + .../Translation/Catalogue/AbstractOperation.php | 146 ++ .../Translation/Catalogue/DiffOperation.php | 55 + .../Translation/Catalogue/MergeOperation.php | 51 + .../Translation/Catalogue/OperationInterface.php | 63 + .../Component/Translation/Dumper/CsvFileDumper.php | 63 + .../Translation/Dumper/DumperInterface.php | 31 + .../Component/Translation/Dumper/FileDumper.php | 122 ++ .../Translation/Dumper/IcuResFileDumper.php | 112 + .../Component/Translation/Dumper/IniFileDumper.php | 45 + .../Translation/Dumper/JsonFileDumper.php | 42 + .../Component/Translation/Dumper/MoFileDumper.php | 82 + .../Component/Translation/Dumper/PhpFileDumper.php | 40 + .../Component/Translation/Dumper/PoFileDumper.php | 61 + .../Component/Translation/Dumper/QtFileDumper.php | 50 + .../Translation/Dumper/XliffFileDumper.php | 109 + .../Translation/Dumper/YamlFileDumper.php | 39 + .../Translation/Exception/ExceptionInterface.php | 23 + .../Exception/InvalidResourceException.php | 23 + .../Exception/NotFoundResourceException.php | 23 + .../Translation/Extractor/ChainExtractor.php | 60 + .../Translation/Extractor/ExtractorInterface.php | 38 + .../Component/Translation/IdentityTranslator.php | 77 + .../Symfony/Component/Translation/Interval.php | 107 + .../Symfony/Component/Translation/LICENSE | 19 + .../Component/Translation/Loader/ArrayLoader.php | 70 + .../Component/Translation/Loader/CsvFileLoader.php | 92 + .../Translation/Loader/IcuDatFileLoader.php | 59 + .../Translation/Loader/IcuResFileLoader.php | 89 + .../Component/Translation/Loader/IniFileLoader.php | 45 + .../Translation/Loader/JsonFileLoader.php | 78 + .../Translation/Loader/LoaderInterface.php | 42 + .../Component/Translation/Loader/MoFileLoader.php | 188 ++ .../Component/Translation/Loader/PhpFileLoader.php | 49 + .../Component/Translation/Loader/PoFileLoader.php | 177 ++ .../Component/Translation/Loader/QtFileLoader.php | 78 + .../Translation/Loader/XliffFileLoader.php | 185 ++ .../Translation/Loader/YamlFileLoader.php | 71 + .../dic/xliff-core/xliff-core-1.2-strict.xsd | 2223 ++++++++++++++++++++ .../Loader/schema/dic/xliff-core/xml.xsd | 309 +++ .../Component/Translation/LoggingTranslator.php | 132 ++ .../Component/Translation/MessageCatalogue.php | 293 +++ .../Translation/MessageCatalogueInterface.php | 172 ++ .../Component/Translation/MessageSelector.php | 90 + .../Translation/MetadataAwareInterface.php | 54 + .../Component/Translation/PluralizationRules.php | 214 ++ .../Symfony/Component/Translation/README.md | 37 + .../Tests/Catalogue/AbstractOperationTest.php | 73 + .../Tests/Catalogue/DiffOperationTest.php | 82 + .../Tests/Catalogue/MergeOperationTest.php | 83 + .../Translation/Tests/Dumper/CsvFileDumperTest.php | 33 + .../Translation/Tests/Dumper/FileDumperTest.php | 70 + .../Tests/Dumper/IcuResFileDumperTest.php | 38 + .../Translation/Tests/Dumper/IniFileDumperTest.php | 32 + .../Tests/Dumper/JsonFileDumperTest.php | 36 + .../Translation/Tests/Dumper/MoFileDumperTest.php | 31 + .../Translation/Tests/Dumper/PhpFileDumperTest.php | 32 + .../Translation/Tests/Dumper/PoFileDumperTest.php | 31 + .../Translation/Tests/Dumper/QtFileDumperTest.php | 32 + .../Tests/Dumper/XliffFileDumperTest.php | 41 + .../Tests/Dumper/YamlFileDumperTest.php | 32 + .../Translation/Tests/IdentityTranslatorTest.php | 95 + .../Component/Translation/Tests/IntervalTest.php | 48 + .../Translation/Tests/Loader/CsvFileLoaderTest.php | 60 + .../Tests/Loader/IcuDatFileLoaderTest.php | 68 + .../Tests/Loader/IcuResFileLoaderTest.php | 55 + .../Translation/Tests/Loader/IniFileLoaderTest.php | 50 + .../Tests/Loader/JsonFileLoaderTest.php | 68 + .../Translation/Tests/Loader/LocalizedTestCase.php | 22 + .../Translation/Tests/Loader/MoFileLoaderTest.php | 71 + .../Translation/Tests/Loader/PhpFileLoaderTest.php | 49 + .../Translation/Tests/Loader/PoFileLoaderTest.php | 96 + .../Translation/Tests/Loader/QtFileLoaderTest.php | 67 + .../Tests/Loader/XliffFileLoaderTest.php | 142 ++ .../Tests/Loader/YamlFileLoaderTest.php | 70 + .../Translation/Tests/LoggingTranslatorTest.php | 56 + .../Translation/Tests/MessageCatalogueTest.php | 200 ++ .../Translation/Tests/MessageSelectorTest.php | 98 + .../Translation/Tests/PluralizationRulesTest.php | 123 ++ .../Translation/Tests/TranslatorCacheTest.php | 231 ++ .../Component/Translation/Tests/TranslatorTest.php | 604 ++++++ .../Tests/fixtures/empty-translation.mo | Bin 0 -> 49 bytes .../Tests/fixtures/empty-translation.po | 3 + .../Component/Translation/Tests/fixtures/empty.csv | 0 .../Component/Translation/Tests/fixtures/empty.ini | 0 .../Translation/Tests/fixtures/empty.json | 0 .../Component/Translation/Tests/fixtures/empty.mo | 0 .../Component/Translation/Tests/fixtures/empty.po | 0 .../Component/Translation/Tests/fixtures/empty.xlf | 0 .../Component/Translation/Tests/fixtures/empty.yml | 0 .../Translation/Tests/fixtures/encoding.xlf | 16 + .../Tests/fixtures/escaped-id-plurals.po | 10 + .../Translation/Tests/fixtures/escaped-id.po | 8 + .../Tests/fixtures/invalid-xml-resources.xlf | 23 + .../Translation/Tests/fixtures/malformed.json | 3 + .../Translation/Tests/fixtures/non-valid.xlf | 11 + .../Translation/Tests/fixtures/non-valid.yml | 1 + .../Translation/Tests/fixtures/plurals.mo | Bin 0 -> 74 bytes .../Translation/Tests/fixtures/plurals.po | 5 + .../Translation/Tests/fixtures/resname.xlf | 19 + .../resourcebundle/corrupted/resources.dat | 1 + .../Tests/fixtures/resourcebundle/dat/en.res | Bin 0 -> 120 bytes .../Tests/fixtures/resourcebundle/dat/en.txt | 3 + .../Tests/fixtures/resourcebundle/dat/fr.res | Bin 0 -> 124 bytes .../Tests/fixtures/resourcebundle/dat/fr.txt | 3 + .../fixtures/resourcebundle/dat/packagelist.txt | 2 + .../fixtures/resourcebundle/dat/resources.dat | Bin 0 -> 352 bytes .../Tests/fixtures/resourcebundle/res/en.res | Bin 0 -> 84 bytes .../Translation/Tests/fixtures/resources-clean.xlf | 22 + .../Translation/Tests/fixtures/resources.csv | 4 + .../Translation/Tests/fixtures/resources.ini | 1 + .../Translation/Tests/fixtures/resources.json | 3 + .../Translation/Tests/fixtures/resources.mo | Bin 0 -> 52 bytes .../Translation/Tests/fixtures/resources.php | 5 + .../Translation/Tests/fixtures/resources.po | 8 + .../Translation/Tests/fixtures/resources.ts | 10 + .../Translation/Tests/fixtures/resources.xlf | 23 + .../Translation/Tests/fixtures/resources.yml | 1 + .../Component/Translation/Tests/fixtures/valid.csv | 4 + .../Translation/Tests/fixtures/withdoctype.xlf | 12 + .../Translation/Tests/fixtures/withnote.xlf | 22 + .../Symfony/Component/Translation/Translator.php | 466 ++++ .../Translation/TranslatorBagInterface.php | 29 + .../Component/Translation/TranslatorInterface.php | 75 + .../Translation/Writer/TranslationWriter.php | 87 + .../Symfony/Component/Translation/composer.json | 43 + .../Symfony/Component/Translation/phpunit.xml.dist | 28 + .../Symfony/Component/Validator/.gitignore | 3 + .../Symfony/Component/Validator/CHANGELOG.md | 159 ++ .../Component/Validator/ClassBasedInterface.php | 30 + .../Symfony/Component/Validator/Constraint.php | 321 +++ .../Component/Validator/ConstraintValidator.php | 216 ++ .../Validator/ConstraintValidatorFactory.php | 51 + .../ConstraintValidatorFactoryInterface.php | 29 + .../Validator/ConstraintValidatorInterface.php | 37 + .../Component/Validator/ConstraintViolation.php | 233 ++ .../Validator/ConstraintViolationInterface.php | 136 ++ .../Validator/ConstraintViolationList.php | 159 ++ .../Validator/ConstraintViolationListInterface.php | 83 + .../Validator/Constraints/AbstractComparison.php | 49 + .../Constraints/AbstractComparisonValidator.php | 74 + .../Component/Validator/Constraints/All.php | 40 + .../Validator/Constraints/AllValidator.php | 58 + .../Component/Validator/Constraints/Blank.php | 27 + .../Validator/Constraints/BlankValidator.php | 40 + .../Component/Validator/Constraints/Callback.php | 77 + .../Validator/Constraints/CallbackValidator.php | 76 + .../Component/Validator/Constraints/CardScheme.php | 47 + .../Validator/Constraints/CardSchemeValidator.php | 122 ++ .../Component/Validator/Constraints/Choice.php | 54 + .../Validator/Constraints/ChoiceValidator.php | 103 + .../Component/Validator/Constraints/Collection.php | 87 + .../Validator/Constraints/Collection/Optional.php | 27 + .../Validator/Constraints/Collection/Required.php | 27 + .../Validator/Constraints/CollectionValidator.php | 94 + .../Component/Validator/Constraints/Composite.php | 152 ++ .../Component/Validator/Constraints/Count.php | 56 + .../Validator/Constraints/CountValidator.php | 60 + .../Component/Validator/Constraints/Country.php | 27 + .../Validator/Constraints/CountryValidator.php | 54 + .../Component/Validator/Constraints/Currency.php | 27 + .../Validator/Constraints/CurrencyValidator.php | 54 + .../Component/Validator/Constraints/Date.php | 35 + .../Component/Validator/Constraints/DateTime.php | 37 + .../Validator/Constraints/DateTimeValidator.php | 68 + .../Validator/Constraints/DateValidator.php | 78 + .../Component/Validator/Constraints/Email.php | 40 + .../Validator/Constraints/EmailValidator.php | 130 ++ .../Component/Validator/Constraints/EqualTo.php | 23 + .../Validator/Constraints/EqualToValidator.php | 28 + .../Component/Validator/Constraints/Existence.php | 30 + .../Component/Validator/Constraints/Expression.php | 59 + .../Validator/Constraints/ExpressionValidator.php | 117 ++ .../Component/Validator/Constraints/False.php | 27 + .../Validator/Constraints/FalseValidator.php | 42 + .../Component/Validator/Constraints/File.php | 86 + .../Validator/Constraints/FileValidator.php | 240 +++ .../Validator/Constraints/GreaterThan.php | 23 + .../Validator/Constraints/GreaterThanOrEqual.php | 23 + .../Constraints/GreaterThanOrEqualValidator.php | 28 + .../Validator/Constraints/GreaterThanValidator.php | 28 + .../Validator/Constraints/GroupSequence.php | 196 ++ .../Constraints/GroupSequenceProvider.php | 22 + .../Component/Validator/Constraints/Iban.php | 41 + .../Validator/Constraints/IbanValidator.php | 143 ++ .../Validator/Constraints/IdenticalTo.php | 23 + .../Validator/Constraints/IdenticalToValidator.php | 28 + .../Component/Validator/Constraints/Image.php | 81 + .../Validator/Constraints/ImageValidator.php | 182 ++ .../Symfony/Component/Validator/Constraints/Ip.php | 82 + .../Validator/Constraints/IpValidator.php | 103 + .../Component/Validator/Constraints/Isbn.php | 65 + .../Validator/Constraints/IsbnValidator.php | 192 ++ .../Component/Validator/Constraints/Issn.php | 44 + .../Validator/Constraints/IssnValidator.php | 132 ++ .../Component/Validator/Constraints/Language.php | 27 + .../Validator/Constraints/LanguageValidator.php | 54 + .../Component/Validator/Constraints/Length.php | 58 + .../Validator/Constraints/LengthValidator.php | 98 + .../Component/Validator/Constraints/LessThan.php | 23 + .../Validator/Constraints/LessThanOrEqual.php | 23 + .../Constraints/LessThanOrEqualValidator.php | 28 + .../Validator/Constraints/LessThanValidator.php | 28 + .../Component/Validator/Constraints/Locale.php | 27 + .../Validator/Constraints/LocaleValidator.php | 54 + .../Component/Validator/Constraints/Luhn.php | 37 + .../Validator/Constraints/LuhnValidator.php | 96 + .../Component/Validator/Constraints/NotBlank.php | 27 + .../Validator/Constraints/NotBlankValidator.php | 40 + .../Component/Validator/Constraints/NotEqualTo.php | 23 + .../Validator/Constraints/NotEqualToValidator.php | 28 + .../Validator/Constraints/NotIdenticalTo.php | 23 + .../Constraints/NotIdenticalToValidator.php | 28 + .../Component/Validator/Constraints/NotNull.php | 27 + .../Validator/Constraints/NotNullValidator.php | 38 + .../Component/Validator/Constraints/Null.php | 27 + .../Validator/Constraints/NullValidator.php | 40 + .../Component/Validator/Constraints/Optional.php | 22 + .../Component/Validator/Constraints/Range.php | 51 + .../Validator/Constraints/RangeValidator.php | 80 + .../Component/Validator/Constraints/Regex.php | 98 + .../Validator/Constraints/RegexValidator.php | 53 + .../Component/Validator/Constraints/Required.php | 22 + .../Component/Validator/Constraints/Time.php | 35 + .../Validator/Constraints/TimeValidator.php | 78 + .../Component/Validator/Constraints/Traverse.php | 54 + .../Component/Validator/Constraints/True.php | 27 + .../Validator/Constraints/TrueValidator.php | 44 + .../Component/Validator/Constraints/Type.php | 44 + .../Validator/Constraints/TypeValidator.php | 56 + .../Component/Validator/Constraints/Url.php | 28 + .../Validator/Constraints/UrlValidator.php | 67 + .../Component/Validator/Constraints/Uuid.php | 77 + .../Validator/Constraints/UuidValidator.php | 264 +++ .../Component/Validator/Constraints/Valid.php | 45 + .../Validator/Context/ExecutionContext.php | 404 ++++ .../Validator/Context/ExecutionContextFactory.php | 64 + .../Context/ExecutionContextFactoryInterface.php | 37 + .../Context/ExecutionContextInterface.php | 226 ++ .../Validator/Context/LegacyExecutionContext.php | 156 ++ .../Context/LegacyExecutionContextFactory.php | 73 + .../Component/Validator/DefaultTranslator.php | 167 ++ .../Validator/Exception/BadMethodCallException.php | 21 + .../Exception/ConstraintDefinitionException.php | 16 + .../Validator/Exception/ExceptionInterface.php | 21 + .../Exception/GroupDefinitionException.php | 16 + .../Exception/InvalidArgumentException.php | 21 + .../Exception/InvalidOptionsException.php | 29 + .../Validator/Exception/MappingException.php | 16 + .../Exception/MissingOptionsException.php | 29 + .../Exception/NoSuchMetadataException.php | 19 + .../Validator/Exception/OutOfBoundsException.php | 21 + .../Validator/Exception/RuntimeException.php | 21 + .../Exception/UnexpectedTypeException.php | 20 + .../Exception/UnsupportedMetadataException.php | 20 + .../Validator/Exception/ValidatorException.php | 16 + .../Component/Validator/ExecutionContext.php | 293 +++ .../Validator/ExecutionContextInterface.php | 329 +++ .../Validator/GlobalExecutionContextInterface.php | 71 + .../Validator/GroupSequenceProviderInterface.php | 26 + .../validator/Symfony/Component/Validator/LICENSE | 19 + .../Validator/Mapping/BlackholeMetadataFactory.php | 24 + .../Component/Validator/Mapping/Cache/ApcCache.php | 55 + .../Validator/Mapping/Cache/CacheInterface.php | 45 + .../Validator/Mapping/Cache/DoctrineCache.php | 69 + .../Validator/Mapping/CascadingStrategy.php | 53 + .../Component/Validator/Mapping/ClassMetadata.php | 548 +++++ .../Validator/Mapping/ClassMetadataFactory.php | 26 + .../Validator/Mapping/ClassMetadataInterface.php | 80 + .../Validator/Mapping/ElementMetadata.php | 24 + .../Mapping/Factory/BlackHoleMetadataFactory.php | 40 + .../Mapping/Factory/LazyLoadingMetadataFactory.php | 153 ++ .../Mapping/Factory/MetadataFactoryInterface.php | 24 + .../Validator/Mapping/GenericMetadata.php | 243 +++ .../Component/Validator/Mapping/GetterMetadata.php | 77 + .../Validator/Mapping/Loader/AbstractLoader.php | 91 + .../Validator/Mapping/Loader/AnnotationLoader.php | 95 + .../Validator/Mapping/Loader/FileLoader.php | 56 + .../Validator/Mapping/Loader/FilesLoader.php | 61 + .../Validator/Mapping/Loader/LoaderChain.php | 62 + .../Validator/Mapping/Loader/LoaderInterface.php | 31 + .../Mapping/Loader/StaticMethodLoader.php | 71 + .../Validator/Mapping/Loader/XmlFileLoader.php | 219 ++ .../Validator/Mapping/Loader/XmlFilesLoader.php | 31 + .../Validator/Mapping/Loader/YamlFileLoader.php | 179 ++ .../Validator/Mapping/Loader/YamlFilesLoader.php | 31 + .../constraint-mapping/constraint-mapping-1.0.xsd | 160 ++ .../Component/Validator/Mapping/MemberMetadata.php | 251 +++ .../Validator/Mapping/MetadataInterface.php | 58 + .../Validator/Mapping/PropertyMetadata.php | 71 + .../Mapping/PropertyMetadataInterface.php | 36 + .../Validator/Mapping/TraversalStrategy.php | 66 + .../Validator/MetadataFactoryInterface.php | 43 + .../Component/Validator/MetadataInterface.php | 73 + .../Validator/ObjectInitializerInterface.php | 35 + .../PropertyMetadataContainerInterface.php | 45 + .../Validator/PropertyMetadataInterface.php | 47 + .../Symfony/Component/Validator/README.md | 126 ++ .../Resources/translations/validators.af.xlf | 227 ++ .../Resources/translations/validators.ar.xlf | 283 +++ .../Resources/translations/validators.az.xlf | 227 ++ .../Resources/translations/validators.bg.xlf | 283 +++ .../Resources/translations/validators.ca.xlf | 307 +++ .../Resources/translations/validators.cs.xlf | 307 +++ .../Resources/translations/validators.cy.xlf | 227 ++ .../Resources/translations/validators.da.xlf | 247 +++ .../Resources/translations/validators.de.xlf | 311 +++ .../Resources/translations/validators.el.xlf | 283 +++ .../Resources/translations/validators.en.xlf | 311 +++ .../Resources/translations/validators.es.xlf | 311 +++ .../Resources/translations/validators.et.xlf | 283 +++ .../Resources/translations/validators.eu.xlf | 283 +++ .../Resources/translations/validators.fa.xlf | 283 +++ .../Resources/translations/validators.fi.xlf | 227 ++ .../Resources/translations/validators.fr.xlf | 311 +++ .../Resources/translations/validators.gl.xlf | 315 +++ .../Resources/translations/validators.he.xlf | 307 +++ .../Resources/translations/validators.hr.xlf | 283 +++ .../Resources/translations/validators.hu.xlf | 311 +++ .../Resources/translations/validators.hy.xlf | 187 ++ .../Resources/translations/validators.id.xlf | 283 +++ .../Resources/translations/validators.it.xlf | 307 +++ .../Resources/translations/validators.ja.xlf | 315 +++ .../Resources/translations/validators.lb.xlf | 303 +++ .../Resources/translations/validators.lt.xlf | 307 +++ .../Resources/translations/validators.mn.xlf | 151 ++ .../Resources/translations/validators.nb.xlf | 155 ++ .../Resources/translations/validators.nl.xlf | 311 +++ .../Resources/translations/validators.no.xlf | 227 ++ .../Resources/translations/validators.pl.xlf | 311 +++ .../Resources/translations/validators.pt.xlf | 307 +++ .../Resources/translations/validators.pt_BR.xlf | 315 +++ .../Resources/translations/validators.ro.xlf | 283 +++ .../Resources/translations/validators.ru.xlf | 311 +++ .../Resources/translations/validators.sk.xlf | 307 +++ .../Resources/translations/validators.sl.xlf | 311 +++ .../Resources/translations/validators.sq.xlf | 227 ++ .../Resources/translations/validators.sr_Cyrl.xlf | 303 +++ .../Resources/translations/validators.sr_Latn.xlf | 303 +++ .../Resources/translations/validators.sv.xlf | 307 +++ .../Resources/translations/validators.th.xlf | 303 +++ .../Resources/translations/validators.tr.xlf | 227 ++ .../Resources/translations/validators.uk.xlf | 283 +++ .../Resources/translations/validators.vi.xlf | 283 +++ .../Resources/translations/validators.zh_CN.xlf | 283 +++ .../Resources/translations/validators.zh_TW.xlf | 283 +++ .../Component/Validator/Tests/ConstraintTest.php | 209 ++ .../Tests/ConstraintViolationListTest.php | 134 ++ .../Validator/Tests/ConstraintViolationTest.php | 55 + .../AbstractComparisonValidatorTestCase.php | 173 ++ .../AbstractConstraintValidatorTest.php | 545 +++++ .../Validator/Tests/Constraints/AllTest.php | 41 + .../Tests/Constraints/AllValidatorTest.php | 93 + .../Tests/Constraints/BlankValidatorTest.php | 69 + .../Tests/Constraints/CallbackValidatorTest.php | 336 +++ .../Tests/Constraints/CardSchemeValidatorTest.php | 133 ++ .../Tests/Constraints/ChoiceValidatorTest.php | 287 +++ .../Validator/Tests/Constraints/CollectionTest.php | 112 + .../CollectionValidatorArrayObjectTest.php | 20 + .../Constraints/CollectionValidatorArrayTest.php | 20 + .../CollectionValidatorCustomArrayObjectTest.php | 22 + .../Tests/Constraints/CollectionValidatorTest.php | 389 ++++ .../Validator/Tests/Constraints/CompositeTest.php | 137 ++ .../Tests/Constraints/CountValidatorArrayTest.php | 23 + .../Constraints/CountValidatorCountableTest.php | 25 + .../Tests/Constraints/CountValidatorTest.php | 203 ++ .../Tests/Constraints/CountryValidatorTest.php | 116 + .../Tests/Constraints/CurrencyValidatorTest.php | 116 + .../Tests/Constraints/DateTimeValidatorTest.php | 110 + .../Tests/Constraints/DateValidatorTest.php | 106 + .../Tests/Constraints/EmailValidatorTest.php | 105 + .../Tests/Constraints/EqualToValidatorTest.php | 69 + .../Tests/Constraints/ExpressionValidatorTest.php | 214 ++ .../Tests/Constraints/FalseValidatorTest.php | 56 + .../Validator/Tests/Constraints/FileTest.php | 107 + .../Tests/Constraints/FileValidatorObjectTest.php | 22 + .../Tests/Constraints/FileValidatorPathTest.php | 36 + .../Tests/Constraints/FileValidatorTest.php | 477 +++++ .../Validator/Tests/Constraints/Fixtures/foo | 0 .../Validator/Tests/Constraints/Fixtures/test.gif | Bin 0 -> 801 bytes .../Tests/Constraints/Fixtures/test_4by3.gif | Bin 0 -> 57 bytes .../Tests/Constraints/Fixtures/test_landscape.gif | Bin 0 -> 43 bytes .../Tests/Constraints/Fixtures/test_portrait.gif | Bin 0 -> 43 bytes .../GreaterThanOrEqualValidatorTest.php | 71 + .../Tests/Constraints/GreaterThanValidatorTest.php | 74 + .../Tests/Constraints/GroupSequenceTest.php | 84 + .../Tests/Constraints/IbanValidatorTest.php | 193 ++ .../Tests/Constraints/IdenticalToValidatorTest.php | 89 + .../Tests/Constraints/ImageValidatorTest.php | 329 +++ .../Tests/Constraints/IpValidatorTest.php | 444 ++++ .../Tests/Constraints/IsbnValidatorTest.php | 271 +++ .../Tests/Constraints/IssnValidatorTest.php | 187 ++ .../Tests/Constraints/LanguageValidatorTest.php | 114 + .../Constraints/LegacyAllValidator2Dot4ApiTest.php | 27 + .../LegacyAllValidatorLegacyApiTest.php | 27 + .../LegacyBlankValidator2Dot4ApiTest.php | 27 + .../LegacyBlankValidatorLegacyApiTest.php | 27 + .../LegacyCallbackValidator2Dot4ApiTest.php | 27 + .../LegacyCallbackValidatorLegacyApiTest.php | 27 + .../LegacyCardSchemeValidator2Dot4ApiTest.php | 27 + .../LegacyCardSchemeValidatorLegacyApiTest.php | 27 + .../LegacyChoiceValidator2Dot4ApiTest.php | 27 + .../LegacyChoiceValidatorLegacyApiTest.php | 27 + .../LegacyCollectionValidatorArray2Dot4ApiTest.php | 25 + ...LegacyCollectionValidatorArrayLegacyApiTest.php | 25 + ...yCollectionValidatorArrayObject2Dot4ApiTest.php | 25 + ...CollectionValidatorArrayObjectLegacyApiTest.php | 25 + ...ctionValidatorCustomArrayObject2Dot4ApiTest.php | 25 + ...tionValidatorCustomArrayObjectLegacyApiTest.php | 25 + .../LegacyCountValidatorArray2Dot4ApiTest.php | 27 + .../LegacyCountValidatorArrayLegacyApiTest.php | 27 + .../LegacyCountValidatorCountable2Dot4ApiTest.php | 27 + .../LegacyCountValidatorCountableLegacyApiTest.php | 27 + .../LegacyCurrencyValidator2Dot4ApiTest.php | 27 + .../LegacyCurrencyValidatorLegacyApiTest.php | 27 + .../LegacyDateTimeValidator2Dot4ApiTest.php | 27 + .../LegacyDateTimeValidatorLegacyApiTest.php | 27 + .../LegacyDateValidator2Dot4ApiTest.php | 27 + .../LegacyDateValidatorLegacyApiTest.php | 27 + .../LegacyEmailValidator2Dot4ApiTest.php | 27 + .../LegacyEmailValidatorLegacyApiTest.php | 27 + .../LegacyEqualToValidator2Dot4ApiTest.php | 27 + .../LegacyEqualToValidatorLegacyApiTest.php | 27 + .../LegacyExpressionValidator2Dot4ApiTest.php | 27 + .../LegacyExpressionValidatorLegacyApiTest.php | 27 + .../LegacyFalseValidator2Dot4ApiTest.php | 27 + .../LegacyFalseValidatorLegacyApiTest.php | 27 + .../LegacyFileValidatorObject2Dot4ApiTest.php | 27 + .../LegacyFileValidatorObjectLegacyApiTest.php | 27 + .../LegacyFileValidatorPath2Dot4ApiTest.php | 27 + .../LegacyFileValidatorPathLegacyApiTest.php | 27 + ...gacyGreaterThanOrEqualValidator2Dot4ApiTest.php | 27 + ...acyGreaterThanOrEqualValidatorLegacyApiTest.php | 27 + .../LegacyGreaterThanValidator2Dot4ApiTest.php | 27 + .../LegacyGreaterThanValidatorLegacyApiTest.php | 27 + .../LegacyIbanValidator2Dot4ApiTest.php | 27 + .../LegacyIbanValidatorLegacyApiTest.php | 27 + .../LegacyIdenticalToValidator2Dot4ApiTest.php | 27 + .../LegacyIdenticalToValidatorLegacyApiTest.php | 27 + .../LegacyImageValidator2Dot4ApiTest.php | 27 + .../LegacyImageValidatorLegacyApiTest.php | 27 + .../Constraints/LegacyIpValidator2Dot4ApiTest.php | 27 + .../Constraints/LegacyIpValidatorLegacyApiTest.php | 27 + .../LegacyIsbnValidator2Dot4ApiTest.php | 27 + .../LegacyIsbnValidatorLegacyApiTest.php | 27 + .../LegacyIssnValidator2Dot4ApiTest.php | 27 + .../LegacyIssnValidatorLegacyApiTest.php | 27 + .../LegacyLanguageValidator2Dot4ApiTest.php | 27 + .../LegacyLanguageValidatorLegacyApiTest.php | 27 + .../LegacyLengthValidator2Dot4ApiTest.php | 27 + .../LegacyLengthValidatorLegacyApiTest.php | 27 + .../LegacyLessThanOrEqualValidator2Dot4ApiTest.php | 27 + ...LegacyLessThanOrEqualValidatorLegacyApiTest.php | 27 + .../LegacyLessThanValidator2Dot4ApiTest.php | 27 + .../LegacyLessThanValidatorLegacyApiTest.php | 27 + .../LegacyLocaleValidator2Dot4ApiTest.php | 27 + .../LegacyLocaleValidatorLegacyApiTest.php | 27 + .../LegacyLuhnValidator2Dot4ApiTest.php | 27 + .../LegacyLuhnValidatorLegacyApiTest.php | 27 + .../LegacyNotBlankValidator2Dot4ApiTest.php | 27 + .../LegacyNotBlankValidatorLegacyApiTest.php | 27 + .../LegacyNotEqualToValidator2Dot4ApiTest.php | 27 + .../LegacyNotEqualToValidatorLegacyApiTest.php | 27 + .../LegacyNotIdenticalToValidator2Dot4ApiTest.php | 27 + .../LegacyNotIdenticalToValidatorLegacyApiTest.php | 27 + .../LegacyNotNullValidator2Dot4ApiTest.php | 27 + .../LegacyNotNullValidatorLegacyApiTest.php | 27 + .../LegacyNullValidator2Dot4ApiTest.php | 27 + .../LegacyNullValidatorLegacyApiTest.php | 27 + .../LegacyRangeValidator2Dot4ApiTest.php | 27 + .../LegacyRangeValidatorLegacyApiTest.php | 27 + .../LegacyRegexValidator2Dot4ApiTest.php | 27 + .../LegacyRegexValidatorLegacyApiTest.php | 27 + .../LegacyTimeValidator2Dot4ApiTest.php | 27 + .../LegacyTimeValidatorLegacyApiTest.php | 27 + .../LegacyTrueValidator2Dot4ApiTest.php | 27 + .../LegacyTrueValidatorLegacyApiTest.php | 27 + .../LegacyTypeValidator2Dot4ApiTest.php | 37 + .../LegacyTypeValidatorLegacyApiTest.php | 29 + .../Constraints/LegacyUrlValidator2Dot4ApiTest.php | 27 + .../LegacyUrlValidatorLegacyApiTest.php | 27 + .../LegacyUuidValidator2Dot4ApiTest.php | 27 + .../LegacyUuidValidatorLegacyApiTest.php | 27 + .../Tests/Constraints/LengthValidatorTest.php | 255 +++ .../Constraints/LessThanOrEqualValidatorTest.php | 74 + .../Tests/Constraints/LessThanValidatorTest.php | 73 + .../Tests/Constraints/LocaleValidatorTest.php | 104 + .../Tests/Constraints/LuhnValidatorTest.php | 127 ++ .../Tests/Constraints/NotBlankValidatorTest.php | 102 + .../Tests/Constraints/NotEqualToValidatorTest.php | 69 + .../Constraints/NotIdenticalToValidatorTest.php | 92 + .../Tests/Constraints/NotNullValidatorTest.php | 60 + .../Tests/Constraints/NullValidatorTest.php | 66 + .../Tests/Constraints/RangeValidatorTest.php | 403 ++++ .../Validator/Tests/Constraints/RegexTest.php | 87 + .../Tests/Constraints/RegexValidatorTest.php | 97 + .../Tests/Constraints/TimeValidatorTest.php | 107 + .../Tests/Constraints/TrueValidatorTest.php | 56 + .../Tests/Constraints/TypeValidatorTest.php | 185 ++ .../Tests/Constraints/UrlValidatorTest.php | 179 ++ .../Tests/Constraints/UuidValidatorTest.php | 211 ++ .../Validator/Tests/Constraints/ValidTest.php | 28 + .../Validator/Tests/Fixtures/CallbackClass.php | 24 + .../Validator/Tests/Fixtures/ClassConstraint.php | 22 + .../Validator/Tests/Fixtures/ConstraintA.php | 31 + .../Tests/Fixtures/ConstraintAValidator.php | 37 + .../Validator/Tests/Fixtures/ConstraintB.php | 23 + .../Validator/Tests/Fixtures/ConstraintC.php | 30 + .../Tests/Fixtures/ConstraintWithValue.php | 31 + .../Fixtures/ConstraintWithValueAsDefault.php | 31 + .../Validator/Tests/Fixtures/Countable.php | 27 + .../Validator/Tests/Fixtures/CustomArrayObject.php | 70 + .../Component/Validator/Tests/Fixtures/Entity.php | 100 + .../Validator/Tests/Fixtures/EntityInterface.php | 16 + .../Validator/Tests/Fixtures/EntityParent.php | 31 + .../Validator/Tests/Fixtures/FailingConstraint.php | 24 + .../Tests/Fixtures/FailingConstraintValidator.php | 23 + .../Validator/Tests/Fixtures/FakeClassMetadata.php | 26 + .../Tests/Fixtures/FakeMetadataFactory.php | 72 + .../Validator/Tests/Fixtures/FilesLoader.php | 39 + .../Tests/Fixtures/GroupSequenceProviderEntity.php | 36 + .../Validator/Tests/Fixtures/InvalidConstraint.php | 18 + .../Tests/Fixtures/InvalidConstraintValidator.php | 16 + .../Tests/Fixtures/LegacyClassMetadata.php | 20 + .../Tests/Fixtures/PropertyConstraint.php | 22 + .../Validator/Tests/Fixtures/Reference.php | 29 + .../Tests/Fixtures/StubGlobalExecutionContext.php | 72 + .../Validator/Tests/LegacyExecutionContextTest.php | 336 +++ .../Tests/Mapping/Cache/DoctrineCacheTest.php | 84 + .../Tests/Mapping/Cache/LegacyApcCacheTest.php | 83 + .../Validator/Tests/Mapping/ClassMetadataTest.php | 280 +++ .../Factory/BlackHoleMetadataFactoryTest.php | 33 + .../Factory/LazyLoadingMetadataFactoryTest.php | 118 ++ .../Validator/Tests/Mapping/GetterMetadataTest.php | 62 + .../Tests/Mapping/LegacyElementMetadataTest.php | 80 + .../Mapping/Loader/AbstractStaticMethodLoader.php | 10 + .../Tests/Mapping/Loader/AnnotationLoaderTest.php | 172 ++ .../Tests/Mapping/Loader/FilesLoaderTest.php | 48 + .../Tests/Mapping/Loader/LoaderChainTest.php | 84 + .../Mapping/Loader/StaticMethodLoaderTest.php | 143 ++ .../Tests/Mapping/Loader/XmlFileLoaderTest.php | 133 ++ .../Tests/Mapping/Loader/YamlFileLoaderTest.php | 123 ++ .../Loader/constraint-mapping-non-strings.xml | 19 + .../Tests/Mapping/Loader/constraint-mapping.xml | 119 ++ .../Tests/Mapping/Loader/constraint-mapping.yml | 62 + .../Tests/Mapping/Loader/empty-mapping.yml | 0 .../Tests/Mapping/Loader/nonvalid-mapping.yml | 1 + .../Validator/Tests/Mapping/Loader/withdoctype.xml | 7 + .../Validator/Tests/Mapping/MemberMetadataTest.php | 110 + .../Tests/Mapping/PropertyMetadataTest.php | 45 + .../Validator/Tests/Util/PropertyPathTest.php | 35 + .../Tests/Validator/Abstract2Dot5ApiTest.php | 776 +++++++ .../Tests/Validator/AbstractLegacyApiTest.php | 315 +++ .../Tests/Validator/AbstractValidatorTest.php | 1288 ++++++++++++ .../Validator/LegacyValidator2Dot5ApiTest.php | 41 + .../Validator/LegacyValidatorLegacyApiTest.php | 41 + .../Validator/RecursiveValidator2Dot5ApiTest.php | 29 + .../Validator/Tests/ValidatorBuilderTest.php | 160 ++ .../Component/Validator/Tests/ValidatorTest.php | 36 + .../Component/Validator/Util/PropertyPath.php | 57 + .../Symfony/Component/Validator/Validation.php | 66 + .../Component/Validator/ValidationVisitor.php | 210 ++ .../Validator/ValidationVisitorInterface.php | 86 + .../Symfony/Component/Validator/Validator.php | 235 +++ .../Validator/ContextualValidatorInterface.php | 89 + .../Validator/Validator/LegacyValidator.php | 79 + .../Validator/RecursiveContextualValidator.php | 866 ++++++++ .../Validator/Validator/RecursiveValidator.php | 140 ++ .../Validator/Validator/ValidatorInterface.php | 100 + .../Component/Validator/ValidatorBuilder.php | 412 ++++ .../Validator/ValidatorBuilderInterface.php | 193 ++ .../Component/Validator/ValidatorInterface.php | 114 + .../Violation/ConstraintViolationBuilder.php | 225 ++ .../ConstraintViolationBuilderInterface.php | 115 + .../Violation/LegacyConstraintViolationBuilder.php | 164 ++ .../Symfony/Component/Validator/composer.json | 56 + .../Symfony/Component/Validator/phpunit.xml.dist | 28 + .../symfony/yaml/Symfony/Component/Yaml/.gitignore | 3 + .../yaml/Symfony/Component/Yaml/CHANGELOG.md | 8 + .../symfony/yaml/Symfony/Component/Yaml/Dumper.php | 73 + .../yaml/Symfony/Component/Yaml/Escaper.php | 97 + .../Component/Yaml/Exception/DumpException.php | 23 + .../Yaml/Exception/ExceptionInterface.php | 23 + .../Component/Yaml/Exception/ParseException.php | 148 ++ .../Component/Yaml/Exception/RuntimeException.php | 23 + .../symfony/yaml/Symfony/Component/Yaml/Inline.php | 546 +++++ vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE | 19 + .../symfony/yaml/Symfony/Component/Yaml/Parser.php | 697 ++++++ .../symfony/yaml/Symfony/Component/Yaml/README.md | 21 + .../Symfony/Component/Yaml/Tests/DumperTest.php | 236 +++ .../Yaml/Tests/Fixtures/YtsAnchorAlias.yml | 31 + .../Yaml/Tests/Fixtures/YtsBasicTests.yml | 202 ++ .../Yaml/Tests/Fixtures/YtsBlockMapping.yml | 51 + .../Yaml/Tests/Fixtures/YtsDocumentSeparator.yml | 85 + .../Yaml/Tests/Fixtures/YtsErrorTests.yml | 25 + .../Yaml/Tests/Fixtures/YtsFlowCollections.yml | 60 + .../Yaml/Tests/Fixtures/YtsFoldedScalars.yml | 176 ++ .../Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml | 45 + .../Tests/Fixtures/YtsSpecificationExamples.yml | 1697 +++++++++++++++ .../Yaml/Tests/Fixtures/YtsTypeTransfers.yml | 244 +++ .../Component/Yaml/Tests/Fixtures/embededPhp.yml | 1 + .../Yaml/Tests/Fixtures/escapedCharacters.yml | 147 ++ .../Component/Yaml/Tests/Fixtures/index.yml | 18 + .../Component/Yaml/Tests/Fixtures/sfComments.yml | 73 + .../Component/Yaml/Tests/Fixtures/sfCompact.yml | 159 ++ .../Component/Yaml/Tests/Fixtures/sfMergeKey.yml | 45 + .../Component/Yaml/Tests/Fixtures/sfObjects.yml | 11 + .../Component/Yaml/Tests/Fixtures/sfQuotes.yml | 33 + .../Component/Yaml/Tests/Fixtures/sfTests.yml | 135 ++ .../Yaml/Tests/Fixtures/unindentedCollections.yml | 82 + .../Symfony/Component/Yaml/Tests/InlineTest.php | 380 ++++ .../Component/Yaml/Tests/ParseExceptionTest.php | 41 + .../Symfony/Component/Yaml/Tests/ParserTest.php | 740 +++++++ .../yaml/Symfony/Component/Yaml/Tests/YamlTest.php | 31 + .../yaml/Symfony/Component/Yaml/Unescaper.php | 141 ++ .../symfony/yaml/Symfony/Component/Yaml/Yaml.php | 100 + .../yaml/Symfony/Component/Yaml/composer.json | 34 + .../yaml/Symfony/Component/Yaml/phpunit.xml.dist | 27 + 1086 files changed, 115895 insertions(+) create mode 100644 .buildpath create mode 100644 .project create mode 100644 .settings/.jsdtscope create mode 100644 .settings/org.eclipse.php.core.prefs create mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 .settings/org.eclipse.wst.jsdt.ui.superType.container create mode 100644 .settings/org.eclipse.wst.jsdt.ui.superType.name create mode 100644 catalog.sql create mode 100644 categories.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/propel.yaml create mode 100644 contact.html create mode 100644 generated-classes/Base/Category.php create mode 100644 generated-classes/Base/CategoryQuery.php create mode 100644 generated-classes/Base/Product.php create mode 100644 generated-classes/Base/ProductCategory.php create mode 100644 generated-classes/Base/ProductCategoryQuery.php create mode 100644 generated-classes/Base/ProductQuery.php create mode 100644 generated-classes/Base/User.php create mode 100644 generated-classes/Base/UserQuery.php create mode 100644 generated-classes/Category.php create mode 100644 generated-classes/CategoryQuery.php create mode 100644 generated-classes/Map/CategoryTableMap.php create mode 100644 generated-classes/Map/ProductCategoryTableMap.php create mode 100644 generated-classes/Map/ProductTableMap.php create mode 100644 generated-classes/Map/UserTableMap.php create mode 100644 generated-classes/Product.php create mode 100644 generated-classes/ProductCategory.php create mode 100644 generated-classes/ProductCategoryQuery.php create mode 100644 generated-classes/ProductQuery.php create mode 100644 generated-classes/User.php create mode 100644 generated-classes/UserQuery.php create mode 100644 generated-conf/config.php create mode 100644 index.html create mode 100644 login.html create mode 100644 productdetails.php create mode 100644 products.php create mode 100644 schema.xml create mode 100644 styles/style.css create mode 100644 vendor.inc.php create mode 100644 vendor/autoload.php create mode 100755 vendor/bin/propel create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/installed.json create mode 160000 vendor/propel/propel create mode 100644 vendor/psr/log/.gitignore create mode 100644 vendor/psr/log/LICENSE create mode 100644 vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 vendor/psr/log/README.md create mode 100644 vendor/psr/log/composer.json create mode 100644 vendor/symfony/config/Symfony/Component/Config/.gitignore create mode 100644 vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md create mode 100644 vendor/symfony/config/Symfony/Component/Config/ConfigCache.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/FileLocator.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/LICENSE create mode 100644 vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/README.md create mode 100644 vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php create mode 100644 vendor/symfony/config/Symfony/Component/Config/composer.json create mode 100644 vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist create mode 100644 vendor/symfony/console/Symfony/Component/Console/.gitignore create mode 100644 vendor/symfony/console/Symfony/Component/Console/Application.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Command/Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/ConsoleEvents.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/DebugFormatterHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/Helper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/HelperInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/ProcessHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/ProgressBar.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/QuestionHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/Table.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/TableSeparator.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Helper/TableStyle.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/ArgvInput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/ArrayInput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/Input.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/InputArgument.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/InputInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/InputOption.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Input/StringInput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/LICENSE create mode 100644 vendor/symfony/console/Symfony/Component/Console/Logger/ConsoleLogger.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Output/NullOutput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Output/Output.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Output/OutputInterface.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Output/StreamOutput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Question/ChoiceQuestion.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Question/ConfirmationQuestion.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Question/Question.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/README.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Resources/bin/hiddeninput.exe create mode 100644 vendor/symfony/console/Symfony/Component/Console/Shell.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DummyOutput.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooCommand.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced1Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced2Command.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyDialogHelperTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyProgressHelperTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyTableHelperTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Logger/ConsoleLoggerTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php create mode 100644 vendor/symfony/console/Symfony/Component/Console/composer.json create mode 100644 vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/FileNotFoundException.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOExceptionInterface.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/LockHandler.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/ExceptionTest.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/LockHandlerTest.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/.gitignore create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Finder.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Glob.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/LICENSE create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/README.md create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/composer.json create mode 100644 vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/.gitignore create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/CHANGELOG.md create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Catalogue/AbstractOperation.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Catalogue/DiffOperation.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Catalogue/MergeOperation.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Catalogue/OperationInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/CsvFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/DumperInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/FileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/IcuResFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/IniFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/JsonFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/MoFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/PhpFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/PoFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/QtFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/XliffFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Dumper/YamlFileDumper.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Exception/InvalidResourceException.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Exception/NotFoundResourceException.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Extractor/ChainExtractor.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Extractor/ExtractorInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/IdentityTranslator.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Interval.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/LICENSE create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/ArrayLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/CsvFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuDatFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuResFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/IniFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/JsonFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/LoaderInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/MoFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/PhpFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/PoFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/QtFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/XliffFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/LoggingTranslator.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogue.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogueInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/MessageSelector.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/MetadataAwareInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/PluralizationRules.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/README.md create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/AbstractOperationTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/DiffOperationTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/MergeOperationTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/JsonFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/MoFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PhpFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PoFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/QtFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/IntervalTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/QtFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/LoggingTranslatorTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageCatalogueTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageSelectorTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/PluralizationRulesTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorCacheTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorTest.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.mo create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.po create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.csv create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.ini create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.json create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.mo create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.po create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.yml create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/encoding.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id-plurals.po create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id.po create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/invalid-xml-resources.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/malformed.json create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.yml create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.mo create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.po create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resname.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/corrupted/resources.dat create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.csv create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ini create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.json create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.mo create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.po create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ts create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.yml create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/valid.csv create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withdoctype.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withnote.xlf create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Translator.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/TranslatorBagInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/TranslatorInterface.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/Writer/TranslationWriter.php create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/composer.json create mode 100644 vendor/symfony/translation/Symfony/Component/Translation/phpunit.xml.dist create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/.gitignore create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraint.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparison.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Composite.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Currency.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/CurrencyValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualTo.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualToValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Existence.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Expression.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/ExpressionValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThan.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Iban.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/IbanValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalTo.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalToValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Isbn.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/IsbnValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Issn.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/IssnValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThan.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqual.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualTo.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualToValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalTo.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Optional.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Required.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Traverse.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Uuid.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/UuidValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContext.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactoryInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContext.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContextFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/DefaultTranslator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/BadMethodCallException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/OutOfBoundsException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/RuntimeException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/UnsupportedMetadataException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/LICENSE create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/DoctrineCache.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/CascadingStrategy.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/BlackHoleMetadataFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/MetadataFactoryInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/GenericMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/MetadataInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadataInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Mapping/TraversalStrategy.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/README.md create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.af.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ar.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.az.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.bg.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ca.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cs.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cy.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.da.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.de.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.el.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.en.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.es.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.et.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.eu.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fa.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fi.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fr.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.gl.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.he.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hr.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hu.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hy.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.id.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.it.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ja.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lb.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lt.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.mn.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nb.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nl.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.no.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pl.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ro.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ru.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sk.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sl.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sq.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Cyrl.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Latn.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sv.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.th.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.tr.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.uk.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.vi.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_TW.xlf create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/foo create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_4by3.gif create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_landscape.gif create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_portrait.gif create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GroupSequenceTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IsbnValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IssnValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArray2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObject2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObjectLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObject2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObjectLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArray2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArrayLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountable2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountableLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObject2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObjectLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPath2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPathLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidator2Dot4ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CallbackClass.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValue.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValueAsDefault.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Countable.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CustomArrayObject.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeClassMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/LegacyClassMetadata.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/StubGlobalExecutionContext.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/LegacyExecutionContextTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/DoctrineCacheTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/LegacyApcCacheTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/BlackHoleMetadataFactoryTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/LegacyElementMetadataTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AbstractStaticMethodLoader.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Util/PropertyPath.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Validation.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Validator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Validator/LegacyValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveValidator.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Validator/ValidatorInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/Violation/LegacyConstraintViolationBuilder.php create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/composer.json create mode 100644 vendor/symfony/validator/Symfony/Component/Validator/phpunit.xml.dist create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/.gitignore create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/CHANGELOG.md create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Escaper.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/README.md create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsAnchorAlias.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBlockMapping.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsDocumentSeparator.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsErrorTests.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFlowCollections.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFoldedScalars.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/embededPhp.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/index.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfComments.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfCompact.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfObjects.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfQuotes.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/unindentedCollections.yml create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParseExceptionTest.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Tests/YamlTest.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/composer.json create mode 100644 vendor/symfony/yaml/Symfony/Component/Yaml/phpunit.xml.dist diff --git a/.buildpath b/.buildpath new file mode 100644 index 0000000..8bcb4b5 --- /dev/null +++ b/.buildpath @@ -0,0 +1,5 @@ + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..2c09027 --- /dev/null +++ b/.project @@ -0,0 +1,34 @@ + + + Catalog + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.dltk.core.scriptbuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.php.core.PHPNature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope new file mode 100644 index 0000000..2f6f983 --- /dev/null +++ b/.settings/.jsdtscope @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.php.core.prefs b/.settings/org.eclipse.php.core.prefs new file mode 100644 index 0000000..a17086f --- /dev/null +++ b/.settings/org.eclipse.php.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +include_path=0;/Catalog diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..fe725be --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.name b/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..05bd71b --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/catalog.sql b/catalog.sql new file mode 100644 index 0000000..20598a2 --- /dev/null +++ b/catalog.sql @@ -0,0 +1,170 @@ +-- phpMyAdmin SQL Dump +-- version 4.4.4 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Erstellungszeit: 05. Mai 2015 um 17:57 +-- Server-Version: 10.0.17-MariaDB-log +-- PHP-Version: 5.6.8 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +-- +-- Datenbank: `catalog` +-- + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `category` +-- + +CREATE TABLE IF NOT EXISTS `category` ( + `id` int(11) NOT NULL COMMENT 'The primary key of the category.', + `name` varchar(100) NOT NULL COMMENT 'The name of the category.', + `description` varchar(1000) DEFAULT NULL COMMENT 'The description of the category.' +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +-- +-- Daten für Tabelle `category` +-- + +INSERT INTO `category` (`id`, `name`, `description`) VALUES +(1, 'Furniture', 'All kind of different furniture and the like.'), +(2, 'Fruits', 'Juicy and delicious fruits.'), +(3, 'Vehicles', 'Everything from one to a million wheels.'); + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `product` +-- + +CREATE TABLE IF NOT EXISTS `product` ( + `id` int(11) NOT NULL COMMENT 'The primary key for the table.', + `name` varchar(100) NOT NULL COMMENT 'The name of the product.', + `price` decimal(10,2) NOT NULL COMMENT 'The price of the product in euro (VAT included).', + `width` int(11) NOT NULL COMMENT 'The width of the product in millimeter.', + `height` int(11) NOT NULL COMMENT 'The height of the product in millimeter.', + `description` varchar(1000) DEFAULT NULL COMMENT 'The description of the product.' +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; + +-- +-- Daten für Tabelle `product` +-- + +INSERT INTO `product` (`id`, `name`, `price`, `width`, `height`, `description`) VALUES +(1, 'Chair', '20.00', 500, 500, 'A chair you can sit in, maybe. Quite comfy, I guess. Probably made of wood or a wood like material.'), +(2, 'Banana', '0.59', 40, 150, 'A long yellow fruit.'), +(3, 'Table', '30.00', 1000, 700, 'A good place for your computer or laptop.'), +(4, 'Apple', '0.31', 100, 100, 'A red or green fruit. Mostly to expensive.'), +(5, 'Motorbike', '1060.32', 1500, 750, 'A car, but only with two wheels and no roof.'), +(6, 'Monstertruck', '5001.10', 3000, 5000, 'Vroom and death.'); + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `product_category` +-- + +CREATE TABLE IF NOT EXISTS `product_category` ( + `product_id` int(11) NOT NULL COMMENT 'The product_id from the product table.', + `category_id` int(11) NOT NULL COMMENT 'The category_id from the category table.' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Daten für Tabelle `product_category` +-- + +INSERT INTO `product_category` (`product_id`, `category_id`) VALUES +(1, 1), +(2, 2), +(3, 1), +(4, 2), +(5, 3), +(6, 3); + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `user` +-- + +CREATE TABLE IF NOT EXISTS `user` ( + `username` varchar(100) NOT NULL COMMENT 'The username of the user.', + `password` char(40) NOT NULL COMMENT 'The password of the user. (sha-1)', + `salt` char(20) NOT NULL COMMENT 'A 20 char salt for the password.' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Daten für Tabelle `user` +-- + +INSERT INTO `user` (`username`, `password`, `salt`) VALUES +('admin', '380dca0ecae4f9eaa1ae5aba87dbf4b9003487cd', 's7nXfQhMXQ9hmNqRT3eT'), +('stefan', 'fafc76665a8a3ac9d13a4367ff6a0820a6aff4d2', '5zNZdAtU77n7CDmPcbxH'); + +-- +-- Indizes der exportierten Tabellen +-- + +-- +-- Indizes für die Tabelle `category` +-- +ALTER TABLE `category` + ADD PRIMARY KEY (`id`); + +-- +-- Indizes für die Tabelle `product` +-- +ALTER TABLE `product` + ADD PRIMARY KEY (`id`); + +-- +-- Indizes für die Tabelle `product_category` +-- +ALTER TABLE `product_category` + ADD PRIMARY KEY (`product_id`,`category_id`), + ADD KEY `category_id` (`category_id`); + +-- +-- Indizes für die Tabelle `user` +-- +ALTER TABLE `user` + ADD PRIMARY KEY (`username`); + +-- +-- AUTO_INCREMENT für exportierte Tabellen +-- + +-- +-- AUTO_INCREMENT für Tabelle `category` +-- +ALTER TABLE `category` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'The primary key of the category.',AUTO_INCREMENT=4; +-- +-- AUTO_INCREMENT für Tabelle `product` +-- +ALTER TABLE `product` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'The primary key for the table.',AUTO_INCREMENT=7; +-- +-- Constraints der exportierten Tabellen +-- + +-- +-- Constraints der Tabelle `product_category` +-- +ALTER TABLE `product_category` + ADD CONSTRAINT `product_category_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`), + ADD CONSTRAINT `product_category_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`); + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/categories.php b/categories.php new file mode 100644 index 0000000..2ef44df --- /dev/null +++ b/categories.php @@ -0,0 +1,35 @@ + + + + +Categories + + + +

Categories

+ +
+
+find(); + + foreach( $categories as $category ){ + echo "
getId()}\">{$category->getName()}
"; + echo "
{$category->getDescription()}
"; + } + +?> +
+
+
+ + + \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..2c3ee33 --- /dev/null +++ b/composer.json @@ -0,0 +1,8 @@ +{ + "require": { + "propel/propel": "~2.0@dev" + }, + "autoload": { + "classmap": ["generated-classes/"] + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..d99d569 --- /dev/null +++ b/composer.lock @@ -0,0 +1,513 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "1d1673037fefda4fc4bc6d10393dc523", + "packages": [ + { + "name": "propel/propel", + "version": "dev-master", + "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." + }, + "bin": [ + "bin/propel" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "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" + ], + "time": "2015-05-01 21:21:08" + }, + { + "name": "psr/log", + "version": "1.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": "" + }, + "type": "library", + "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" + ], + "time": "2012-12-21 11:40:51" + }, + { + "name": "symfony/config", + "version": "v2.6.6", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "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", + "time": "2015-03-30 15:54:10" + }, + { + "name": "symfony/console", + "version": "v2.6.6", + "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": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "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", + "time": "2015-03-30 15:54:10" + }, + { + "name": "symfony/filesystem", + "version": "v2.6.6", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "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", + "time": "2015-03-22 16:55:57" + }, + { + "name": "symfony/finder", + "version": "v2.6.6", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "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", + "time": "2015-03-30 15:54:10" + }, + { + "name": "symfony/translation", + "version": "v2.6.6", + "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": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "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", + "time": "2015-03-30 15:54:10" + }, + { + "name": "symfony/validator", + "version": "v2.6.6", + "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": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "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", + "time": "2015-03-30 15:54:10" + }, + { + "name": "symfony/yaml", + "version": "v2.6.6", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "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", + "time": "2015-03-30 15:54:10" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "propel/propel": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/config/propel.yaml b/config/propel.yaml new file mode 100644 index 0000000..135f44c --- /dev/null +++ b/config/propel.yaml @@ -0,0 +1,46 @@ +## Sample Propel configuration file ## + +propel: +## General settings ## + general: + # The name of your project. + # This affects names of generated files, etc. + project: catalog + version: 1.0.0-dev + + ## All Database settings ## + # + # This section replaces the old runtime-conf.xml file and it's also used by config:convert command + database: + # All database sources + connections: + default: + adapter: mysql + # Connection class. While developing you could use Propel\Runtime\Connection\DebugPDO + classname: Propel\Runtime\Connection\ConnectionWrapper + dsn: "mysql:host=localhost;dbname=catalog" + user: root + password: + # Driver options. See http://www.php.net/manual/en/pdo.construct.php + # options must be passed to the contructor of the connection object + options: + # See http://www.php.net/manual/en/pdo.getattribute.php + # Attributes are set via `setAttribute()` method, after the connection object is created + attributes: + #Propel specific settings + settings: + charset: utf8 + + ## Runtime settings ## + runtime: + defaultConnection: default + # Datasources as defined in database.connections + connections: + - default + + ## Generator settings ## + generator: + defaultConnection: default + # Datasources as defined in database.connections + connections: + - default diff --git a/contact.html b/contact.html new file mode 100644 index 0000000..89b609f --- /dev/null +++ b/contact.html @@ -0,0 +1,23 @@ + + + + +Contact Us + + + +

Contact us

+ +
+

Name: SomeCompany Ltd.
Telephone: +1-555-6383
Address: SomeStreet in Alamo

+
+
+ + + \ No newline at end of file diff --git a/generated-classes/Base/Category.php b/generated-classes/Base/Category.php new file mode 100644 index 0000000..b9916f8 --- /dev/null +++ b/generated-classes/Base/Category.php @@ -0,0 +1,1816 @@ +modifiedColumns; + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return $this->modifiedColumns && isset($this->modifiedColumns[$col]); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return $this->modifiedColumns ? array_keys($this->modifiedColumns) : []; + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return boolean true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + if (isset($this->modifiedColumns[$col])) { + unset($this->modifiedColumns[$col]); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another Category instance. If + * obj is an instance of Category, delegates to + * equals(Category). Otherwise, returns false. + * + * @param mixed $obj The object to compare to. + * @return boolean Whether equal to the object specified. + */ + public function equals($obj) + { + if (!$obj instanceof static) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @param string $name The virtual column name + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @param string $name The virtual column name + * @return mixed + * + * @throws PropelException + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return $this|Category The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Get the [name] column value. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Get the [description] column value. + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return $this|\Category The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[CategoryTableMap::COL_ID] = true; + } + + return $this; + } // setId() + + /** + * Set the value of [name] column. + * + * @param string $v new value + * @return $this|\Category The current object (for fluent API support) + */ + public function setName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->name !== $v) { + $this->name = $v; + $this->modifiedColumns[CategoryTableMap::COL_NAME] = true; + } + + return $this; + } // setName() + + /** + * Set the value of [description] column. + * + * @param string $v new value + * @return $this|\Category The current object (for fluent API support) + */ + public function setDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->description !== $v) { + $this->description = $v; + $this->modifiedColumns[CategoryTableMap::COL_DESCRIPTION] = true; + } + + return $this; + } // setDescription() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : CategoryTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : CategoryTableMap::translateFieldName('Name', TableMap::TYPE_PHPNAME, $indexType)]; + $this->name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : CategoryTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 3; // 3 = CategoryTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException(sprintf('Error populating %s object', '\\Category'), 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(CategoryTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildCategoryQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->collProductCategories = null; + + $this->collProducts = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see Category::setDeleted() + * @see Category::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(CategoryTableMap::DATABASE_NAME); + } + + $con->transaction(function () use ($con) { + $deleteQuery = ChildCategoryQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $this->setDeleted(true); + } + }); + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(CategoryTableMap::DATABASE_NAME); + } + + return $con->transaction(function () use ($con) { + $isInsert = $this->isNew(); + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + } else { + $ret = $ret && $this->preUpdate($con); + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + CategoryTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + + return $affectedRows; + }); + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + $affectedRows += 1; + } else { + $affectedRows += $this->doUpdate($con); + } + $this->resetModified(); + } + + if ($this->productsScheduledForDeletion !== null) { + if (!$this->productsScheduledForDeletion->isEmpty()) { + $pks = array(); + foreach ($this->productsScheduledForDeletion as $entry) { + $entryPk = []; + + $entryPk[1] = $this->getId(); + $entryPk[0] = $entry->getId(); + $pks[] = $entryPk; + } + + \ProductCategoryQuery::create() + ->filterByPrimaryKeys($pks) + ->delete($con); + + $this->productsScheduledForDeletion = null; + } + + } + + if ($this->collProducts) { + foreach ($this->collProducts as $product) { + if (!$product->isDeleted() && ($product->isNew() || $product->isModified())) { + $product->save($con); + } + } + } + + + if ($this->productCategoriesScheduledForDeletion !== null) { + if (!$this->productCategoriesScheduledForDeletion->isEmpty()) { + \ProductCategoryQuery::create() + ->filterByPrimaryKeys($this->productCategoriesScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->productCategoriesScheduledForDeletion = null; + } + } + + if ($this->collProductCategories !== null) { + foreach ($this->collProductCategories as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[CategoryTableMap::COL_ID] = true; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . CategoryTableMap::COL_ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(CategoryTableMap::COL_ID)) { + $modifiedColumns[':p' . $index++] = 'id'; + } + if ($this->isColumnModified(CategoryTableMap::COL_NAME)) { + $modifiedColumns[':p' . $index++] = 'name'; + } + if ($this->isColumnModified(CategoryTableMap::COL_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'description'; + } + + $sql = sprintf( + 'INSERT INTO category (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'id': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'name': + $stmt->bindValue($identifier, $this->name, PDO::PARAM_STR); + break; + case 'description': + $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = CategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getName(); + break; + case 2: + return $this->getDescription(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + + if (isset($alreadyDumpedObjects['Category'][$this->hashCode()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['Category'][$this->hashCode()] = true; + $keys = CategoryTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getName(), + $keys[2] => $this->getDescription(), + ); + $virtualColumns = $this->virtualColumns; + foreach ($virtualColumns as $key => $virtualColumn) { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->collProductCategories) { + + switch ($keyType) { + case TableMap::TYPE_CAMELNAME: + $key = 'productCategories'; + break; + case TableMap::TYPE_FIELDNAME: + $key = 'product_categories'; + break; + default: + $key = 'ProductCategories'; + } + + $result[$key] = $this->collProductCategories->toArray(null, false, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return $this|\Category + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = CategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return $this|\Category + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setName($value); + break; + case 2: + $this->setDescription($value); + break; + } // switch() + + return $this; + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = CategoryTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) { + $this->setId($arr[$keys[0]]); + } + if (array_key_exists($keys[1], $arr)) { + $this->setName($arr[$keys[1]]); + } + if (array_key_exists($keys[2], $arr)) { + $this->setDescription($arr[$keys[2]]); + } + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * @param string $keyType The type of keys the array uses. + * + * @return $this|\Category The current object, for fluid interface + */ + public function importFrom($parser, $data, $keyType = TableMap::TYPE_PHPNAME) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + $this->fromArray($parser->toArray($data), $keyType); + + return $this; + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CategoryTableMap::DATABASE_NAME); + + if ($this->isColumnModified(CategoryTableMap::COL_ID)) { + $criteria->add(CategoryTableMap::COL_ID, $this->id); + } + if ($this->isColumnModified(CategoryTableMap::COL_NAME)) { + $criteria->add(CategoryTableMap::COL_NAME, $this->name); + } + if ($this->isColumnModified(CategoryTableMap::COL_DESCRIPTION)) { + $criteria->add(CategoryTableMap::COL_DESCRIPTION, $this->description); + } + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @throws LogicException if no primary key is defined + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = ChildCategoryQuery::create(); + $criteria->add(CategoryTableMap::COL_ID, $this->id); + + return $criteria; + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + $validPk = null !== $this->getId(); + + $validPrimaryKeyFKs = 0; + $primaryKeyFKs = []; + + if ($validPk) { + return crc32(json_encode($this->getPrimaryKey(), JSON_UNESCAPED_UNICODE)); + } elseif ($validPrimaryKeyFKs) { + return crc32(json_encode($primaryKeyFKs, JSON_UNESCAPED_UNICODE)); + } + + return spl_object_hash($this); + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Category (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setName($this->getName()); + $copyObj->setDescription($this->getDescription()); + + if ($deepCopy) { + // important: temporarily setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + $copyObj->setNew(false); + + foreach ($this->getProductCategories() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addProductCategory($relObj->copy($deepCopy)); + } + } + + } // if ($deepCopy) + + if ($makeNew) { + $copyObj->setNew(true); + $copyObj->setId(NULL); // this is a auto-increment column, so set to default value + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Category Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + + /** + * Initializes a collection based on the name of a relation. + * Avoids crafting an 'init[$relationName]s' method name + * that wouldn't work when StandardEnglishPluralizer is used. + * + * @param string $relationName The name of the relation to initialize + * @return void + */ + public function initRelation($relationName) + { + if ('ProductCategory' == $relationName) { + return $this->initProductCategories(); + } + } + + /** + * Clears out the collProductCategories collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addProductCategories() + */ + public function clearProductCategories() + { + $this->collProductCategories = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collProductCategories collection loaded partially. + */ + public function resetPartialProductCategories($v = true) + { + $this->collProductCategoriesPartial = $v; + } + + /** + * Initializes the collProductCategories collection. + * + * By default this just sets the collProductCategories collection to an empty array (like clearcollProductCategories()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initProductCategories($overrideExisting = true) + { + if (null !== $this->collProductCategories && !$overrideExisting) { + return; + } + $this->collProductCategories = new ObjectCollection(); + $this->collProductCategories->setModel('\ProductCategory'); + } + + /** + * Gets an array of ChildProductCategory objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildCategory is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return ObjectCollection|ChildProductCategory[] List of ChildProductCategory objects + * @throws PropelException + */ + public function getProductCategories(Criteria $criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collProductCategoriesPartial && !$this->isNew(); + if (null === $this->collProductCategories || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductCategories) { + // return empty collection + $this->initProductCategories(); + } else { + $collProductCategories = ChildProductCategoryQuery::create(null, $criteria) + ->filterByCategory($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collProductCategoriesPartial && count($collProductCategories)) { + $this->initProductCategories(false); + + foreach ($collProductCategories as $obj) { + if (false == $this->collProductCategories->contains($obj)) { + $this->collProductCategories->append($obj); + } + } + + $this->collProductCategoriesPartial = true; + } + + return $collProductCategories; + } + + if ($partial && $this->collProductCategories) { + foreach ($this->collProductCategories as $obj) { + if ($obj->isNew()) { + $collProductCategories[] = $obj; + } + } + } + + $this->collProductCategories = $collProductCategories; + $this->collProductCategoriesPartial = false; + } + } + + return $this->collProductCategories; + } + + /** + * Sets a collection of ChildProductCategory objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $productCategories A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return $this|ChildCategory The current object (for fluent API support) + */ + public function setProductCategories(Collection $productCategories, ConnectionInterface $con = null) + { + /** @var ChildProductCategory[] $productCategoriesToDelete */ + $productCategoriesToDelete = $this->getProductCategories(new Criteria(), $con)->diff($productCategories); + + + //since at least one column in the foreign key is at the same time a PK + //we can not just set a PK to NULL in the lines below. We have to store + //a backup of all values, so we are able to manipulate these items based on the onDelete value later. + $this->productCategoriesScheduledForDeletion = clone $productCategoriesToDelete; + + foreach ($productCategoriesToDelete as $productCategoryRemoved) { + $productCategoryRemoved->setCategory(null); + } + + $this->collProductCategories = null; + foreach ($productCategories as $productCategory) { + $this->addProductCategory($productCategory); + } + + $this->collProductCategories = $productCategories; + $this->collProductCategoriesPartial = false; + + return $this; + } + + /** + * Returns the number of related ProductCategory objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related ProductCategory objects. + * @throws PropelException + */ + public function countProductCategories(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collProductCategoriesPartial && !$this->isNew(); + if (null === $this->collProductCategories || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductCategories) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getProductCategories()); + } + + $query = ChildProductCategoryQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByCategory($this) + ->count($con); + } + + return count($this->collProductCategories); + } + + /** + * Method called to associate a ChildProductCategory object to this object + * through the ChildProductCategory foreign key attribute. + * + * @param ChildProductCategory $l ChildProductCategory + * @return $this|\Category The current object (for fluent API support) + */ + public function addProductCategory(ChildProductCategory $l) + { + if ($this->collProductCategories === null) { + $this->initProductCategories(); + $this->collProductCategoriesPartial = true; + } + + if (!$this->collProductCategories->contains($l)) { + $this->doAddProductCategory($l); + } + + return $this; + } + + /** + * @param ChildProductCategory $productCategory The ChildProductCategory object to add. + */ + protected function doAddProductCategory(ChildProductCategory $productCategory) + { + $this->collProductCategories[]= $productCategory; + $productCategory->setCategory($this); + } + + /** + * @param ChildProductCategory $productCategory The ChildProductCategory object to remove. + * @return $this|ChildCategory The current object (for fluent API support) + */ + public function removeProductCategory(ChildProductCategory $productCategory) + { + if ($this->getProductCategories()->contains($productCategory)) { + $pos = $this->collProductCategories->search($productCategory); + $this->collProductCategories->remove($pos); + if (null === $this->productCategoriesScheduledForDeletion) { + $this->productCategoriesScheduledForDeletion = clone $this->collProductCategories; + $this->productCategoriesScheduledForDeletion->clear(); + } + $this->productCategoriesScheduledForDeletion[]= clone $productCategory; + $productCategory->setCategory(null); + } + + return $this; + } + + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this Category is new, it will return + * an empty collection; or if this Category has previously + * been saved, it will retrieve related ProductCategories from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in Category. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) + * @return ObjectCollection|ChildProductCategory[] List of ChildProductCategory objects + */ + public function getProductCategoriesJoinProduct(Criteria $criteria = null, ConnectionInterface $con = null, $joinBehavior = Criteria::LEFT_JOIN) + { + $query = ChildProductCategoryQuery::create(null, $criteria); + $query->joinWith('Product', $joinBehavior); + + return $this->getProductCategories($query, $con); + } + + /** + * Clears out the collProducts collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addProducts() + */ + public function clearProducts() + { + $this->collProducts = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Initializes the collProducts crossRef collection. + * + * By default this just sets the collProducts collection to an empty collection (like clearProducts()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @return void + */ + public function initProducts() + { + $this->collProducts = new ObjectCollection(); + $this->collProductsPartial = true; + + $this->collProducts->setModel('\Product'); + } + + /** + * Checks if the collProducts collection is loaded. + * + * @return bool + */ + public function isProductsLoaded() + { + return null !== $this->collProducts; + } + + /** + * Gets a collection of ChildProduct objects related by a many-to-many relationship + * to the current object by way of the product_category cross-reference table. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildCategory is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria Optional query object to filter the query + * @param ConnectionInterface $con Optional connection object + * + * @return ObjectCollection|ChildProduct[] List of ChildProduct objects + */ + public function getProducts(Criteria $criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collProductsPartial && !$this->isNew(); + if (null === $this->collProducts || null !== $criteria || $partial) { + if ($this->isNew()) { + // return empty collection + if (null === $this->collProducts) { + $this->initProducts(); + } + } else { + + $query = ChildProductQuery::create(null, $criteria) + ->filterByCategory($this); + $collProducts = $query->find($con); + if (null !== $criteria) { + return $collProducts; + } + + if ($partial && $this->collProducts) { + //make sure that already added objects gets added to the list of the database. + foreach ($this->collProducts as $obj) { + if (!$collProducts->contains($obj)) { + $collProducts[] = $obj; + } + } + } + + $this->collProducts = $collProducts; + $this->collProductsPartial = false; + } + } + + return $this->collProducts; + } + + /** + * Sets a collection of Product objects related by a many-to-many relationship + * to the current object by way of the product_category cross-reference table. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $products A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return $this|ChildCategory The current object (for fluent API support) + */ + public function setProducts(Collection $products, ConnectionInterface $con = null) + { + $this->clearProducts(); + $currentProducts = $this->getProducts(); + + $productsScheduledForDeletion = $currentProducts->diff($products); + + foreach ($productsScheduledForDeletion as $toDelete) { + $this->removeProduct($toDelete); + } + + foreach ($products as $product) { + if (!$currentProducts->contains($product)) { + $this->doAddProduct($product); + } + } + + $this->collProductsPartial = false; + $this->collProducts = $products; + + return $this; + } + + /** + * Gets the number of Product objects related by a many-to-many relationship + * to the current object by way of the product_category cross-reference table. + * + * @param Criteria $criteria Optional query object to filter the query + * @param boolean $distinct Set to true to force count distinct + * @param ConnectionInterface $con Optional connection object + * + * @return int the number of related Product objects + */ + public function countProducts(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collProductsPartial && !$this->isNew(); + if (null === $this->collProducts || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProducts) { + return 0; + } else { + + if ($partial && !$criteria) { + return count($this->getProducts()); + } + + $query = ChildProductQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByCategory($this) + ->count($con); + } + } else { + return count($this->collProducts); + } + } + + /** + * Associate a ChildProduct to this object + * through the product_category cross reference table. + * + * @param ChildProduct $product + * @return ChildCategory The current object (for fluent API support) + */ + public function addProduct(ChildProduct $product) + { + if ($this->collProducts === null) { + $this->initProducts(); + } + + if (!$this->getProducts()->contains($product)) { + // only add it if the **same** object is not already associated + $this->collProducts->push($product); + $this->doAddProduct($product); + } + + return $this; + } + + /** + * + * @param ChildProduct $product + */ + protected function doAddProduct(ChildProduct $product) + { + $productCategory = new ChildProductCategory(); + + $productCategory->setProduct($product); + + $productCategory->setCategory($this); + + $this->addProductCategory($productCategory); + + // set the back reference to this object directly as using provided method either results + // in endless loop or in multiple relations + if (!$product->isCategoriesLoaded()) { + $product->initCategories(); + $product->getCategories()->push($this); + } elseif (!$product->getCategories()->contains($this)) { + $product->getCategories()->push($this); + } + + } + + /** + * Remove product of this object + * through the product_category cross reference table. + * + * @param ChildProduct $product + * @return ChildCategory The current object (for fluent API support) + */ + public function removeProduct(ChildProduct $product) + { + if ($this->getProducts()->contains($product)) { $productCategory = new ChildProductCategory(); + + $productCategory->setProduct($product); + if ($product->isCategoriesLoaded()) { + //remove the back reference if available + $product->getCategories()->removeObject($this); + } + + $productCategory->setCategory($this); + $this->removeProductCategory(clone $productCategory); + $productCategory->clear(); + + $this->collProducts->remove($this->collProducts->search($product)); + + if (null === $this->productsScheduledForDeletion) { + $this->productsScheduledForDeletion = clone $this->collProducts; + $this->productsScheduledForDeletion->clear(); + } + + $this->productsScheduledForDeletion->push($product); + } + + + return $this; + } + + /** + * Clears the current object, sets all attributes to their default values and removes + * outgoing references as well as back-references (from other objects to this one. Results probably in a database + * change of those foreign objects when you call `save` there). + */ + public function clear() + { + $this->id = null; + $this->name = null; + $this->description = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references and back-references to other model objects or collections of model objects. + * + * This method is used to reset all php object references (not the actual reference in the database). + * Necessary for object serialisation. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + if ($this->collProductCategories) { + foreach ($this->collProductCategories as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collProducts) { + foreach ($this->collProducts as $o) { + $o->clearAllReferences($deep); + } + } + } // if ($deep) + + $this->collProductCategories = null; + $this->collProducts = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(CategoryTableMap::DEFAULT_STRING_FORMAT); + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/generated-classes/Base/CategoryQuery.php b/generated-classes/Base/CategoryQuery.php new file mode 100644 index 0000000..4711525 --- /dev/null +++ b/generated-classes/Base/CategoryQuery.php @@ -0,0 +1,507 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildCategory|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, ConnectionInterface $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = CategoryTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(CategoryTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @throws \Propel\Runtime\Exception\PropelException + * + * @return ChildCategory A model object, or null if the key is not found + */ + protected function findPkSimple($key, ConnectionInterface $con) + { + $sql = 'SELECT id, name, description FROM category WHERE id = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + /** @var ChildCategory $obj */ + $obj = new ChildCategory(); + $obj->hydrate($row); + CategoryTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildCategory|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, ConnectionInterface $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return $this|ChildCategoryQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(CategoryTableMap::COL_ID, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return $this|ChildCategoryQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(CategoryTableMap::COL_ID, $keys, Criteria::IN); + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @param mixed $id The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildCategoryQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(CategoryTableMap::COL_ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(CategoryTableMap::COL_ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(CategoryTableMap::COL_ID, $id, $comparison); + } + + /** + * Filter the query on the name column + * + * Example usage: + * + * $query->filterByName('fooValue'); // WHERE name = 'fooValue' + * $query->filterByName('%fooValue%'); // WHERE name LIKE '%fooValue%' + * + * + * @param string $name The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildCategoryQuery The current query, for fluid interface + */ + public function filterByName($name = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($name)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $name)) { + $name = str_replace('*', '%', $name); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(CategoryTableMap::COL_NAME, $name, $comparison); + } + + /** + * Filter the query on the description column + * + * Example usage: + * + * $query->filterByDescription('fooValue'); // WHERE description = 'fooValue' + * $query->filterByDescription('%fooValue%'); // WHERE description LIKE '%fooValue%' + * + * + * @param string $description The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildCategoryQuery The current query, for fluid interface + */ + public function filterByDescription($description = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($description)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $description)) { + $description = str_replace('*', '%', $description); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(CategoryTableMap::COL_DESCRIPTION, $description, $comparison); + } + + /** + * Filter the query by a related \ProductCategory object + * + * @param \ProductCategory|ObjectCollection $productCategory the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildCategoryQuery The current query, for fluid interface + */ + public function filterByProductCategory($productCategory, $comparison = null) + { + if ($productCategory instanceof \ProductCategory) { + return $this + ->addUsingAlias(CategoryTableMap::COL_ID, $productCategory->getCategoryId(), $comparison); + } elseif ($productCategory instanceof ObjectCollection) { + return $this + ->useProductCategoryQuery() + ->filterByPrimaryKeys($productCategory->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByProductCategory() only accepts arguments of type \ProductCategory or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the ProductCategory relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return $this|ChildCategoryQuery The current query, for fluid interface + */ + public function joinProductCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('ProductCategory'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'ProductCategory'); + } + + return $this; + } + + /** + * Use the ProductCategory relation ProductCategory object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \ProductCategoryQuery A secondary query class using the current class as primary query + */ + public function useProductCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinProductCategory($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ProductCategory', '\ProductCategoryQuery'); + } + + /** + * Filter the query by a related Product object + * using the product_category table as cross reference + * + * @param Product $product the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildCategoryQuery The current query, for fluid interface + */ + public function filterByProduct($product, $comparison = Criteria::EQUAL) + { + return $this + ->useProductCategoryQuery() + ->filterByProduct($product, $comparison) + ->endUse(); + } + + /** + * Exclude object from result + * + * @param ChildCategory $category Object to remove from the list of results + * + * @return $this|ChildCategoryQuery The current query, for fluid interface + */ + public function prune($category = null) + { + if ($category) { + $this->addUsingAlias(CategoryTableMap::COL_ID, $category->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the category table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(CategoryTableMap::DATABASE_NAME); + } + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con) { + $affectedRows = 0; // initialize var to track total num of affected rows + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + CategoryTableMap::clearInstancePool(); + CategoryTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + + /** + * Performs a DELETE on the database based on the current ModelCriteria + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(CategoryTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(CategoryTableMap::DATABASE_NAME); + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con, $criteria) { + $affectedRows = 0; // initialize var to track total num of affected rows + + CategoryTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + CategoryTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + +} // CategoryQuery diff --git a/generated-classes/Base/Product.php b/generated-classes/Base/Product.php new file mode 100644 index 0000000..6bcf48d --- /dev/null +++ b/generated-classes/Base/Product.php @@ -0,0 +1,1996 @@ +modifiedColumns; + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return $this->modifiedColumns && isset($this->modifiedColumns[$col]); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return $this->modifiedColumns ? array_keys($this->modifiedColumns) : []; + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return boolean true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + if (isset($this->modifiedColumns[$col])) { + unset($this->modifiedColumns[$col]); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another Product instance. If + * obj is an instance of Product, delegates to + * equals(Product). Otherwise, returns false. + * + * @param mixed $obj The object to compare to. + * @return boolean Whether equal to the object specified. + */ + public function equals($obj) + { + if (!$obj instanceof static) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @param string $name The virtual column name + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @param string $name The virtual column name + * @return mixed + * + * @throws PropelException + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return $this|Product The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Get the [name] column value. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Get the [price] column value. + * + * @return string + */ + public function getPrice() + { + return $this->price; + } + + /** + * Get the [width] column value. + * + * @return int + */ + public function getWidth() + { + return $this->width; + } + + /** + * Get the [height] column value. + * + * @return int + */ + public function getHeight() + { + return $this->height; + } + + /** + * Get the [description] column value. + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return $this|\Product The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[ProductTableMap::COL_ID] = true; + } + + return $this; + } // setId() + + /** + * Set the value of [name] column. + * + * @param string $v new value + * @return $this|\Product The current object (for fluent API support) + */ + public function setName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->name !== $v) { + $this->name = $v; + $this->modifiedColumns[ProductTableMap::COL_NAME] = true; + } + + return $this; + } // setName() + + /** + * Set the value of [price] column. + * + * @param string $v new value + * @return $this|\Product The current object (for fluent API support) + */ + public function setPrice($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->price !== $v) { + $this->price = $v; + $this->modifiedColumns[ProductTableMap::COL_PRICE] = true; + } + + return $this; + } // setPrice() + + /** + * Set the value of [width] column. + * + * @param int $v new value + * @return $this|\Product The current object (for fluent API support) + */ + public function setWidth($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->width !== $v) { + $this->width = $v; + $this->modifiedColumns[ProductTableMap::COL_WIDTH] = true; + } + + return $this; + } // setWidth() + + /** + * Set the value of [height] column. + * + * @param int $v new value + * @return $this|\Product The current object (for fluent API support) + */ + public function setHeight($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->height !== $v) { + $this->height = $v; + $this->modifiedColumns[ProductTableMap::COL_HEIGHT] = true; + } + + return $this; + } // setHeight() + + /** + * Set the value of [description] column. + * + * @param string $v new value + * @return $this|\Product The current object (for fluent API support) + */ + public function setDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->description !== $v) { + $this->description = $v; + $this->modifiedColumns[ProductTableMap::COL_DESCRIPTION] = true; + } + + return $this; + } // setDescription() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ProductTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ProductTableMap::translateFieldName('Name', TableMap::TYPE_PHPNAME, $indexType)]; + $this->name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ProductTableMap::translateFieldName('Price', TableMap::TYPE_PHPNAME, $indexType)]; + $this->price = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ProductTableMap::translateFieldName('Width', TableMap::TYPE_PHPNAME, $indexType)]; + $this->width = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProductTableMap::translateFieldName('Height', TableMap::TYPE_PHPNAME, $indexType)]; + $this->height = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 6; // 6 = ProductTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException(sprintf('Error populating %s object', '\\Product'), 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildProductQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->collProductCategories = null; + + $this->collCategories = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see Product::setDeleted() + * @see Product::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductTableMap::DATABASE_NAME); + } + + $con->transaction(function () use ($con) { + $deleteQuery = ChildProductQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $this->setDeleted(true); + } + }); + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductTableMap::DATABASE_NAME); + } + + return $con->transaction(function () use ($con) { + $isInsert = $this->isNew(); + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + } else { + $ret = $ret && $this->preUpdate($con); + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + ProductTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + + return $affectedRows; + }); + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + $affectedRows += 1; + } else { + $affectedRows += $this->doUpdate($con); + } + $this->resetModified(); + } + + if ($this->categoriesScheduledForDeletion !== null) { + if (!$this->categoriesScheduledForDeletion->isEmpty()) { + $pks = array(); + foreach ($this->categoriesScheduledForDeletion as $entry) { + $entryPk = []; + + $entryPk[0] = $this->getId(); + $entryPk[1] = $entry->getId(); + $pks[] = $entryPk; + } + + \ProductCategoryQuery::create() + ->filterByPrimaryKeys($pks) + ->delete($con); + + $this->categoriesScheduledForDeletion = null; + } + + } + + if ($this->collCategories) { + foreach ($this->collCategories as $category) { + if (!$category->isDeleted() && ($category->isNew() || $category->isModified())) { + $category->save($con); + } + } + } + + + if ($this->productCategoriesScheduledForDeletion !== null) { + if (!$this->productCategoriesScheduledForDeletion->isEmpty()) { + \ProductCategoryQuery::create() + ->filterByPrimaryKeys($this->productCategoriesScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->productCategoriesScheduledForDeletion = null; + } + } + + if ($this->collProductCategories !== null) { + foreach ($this->collProductCategories as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[ProductTableMap::COL_ID] = true; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . ProductTableMap::COL_ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(ProductTableMap::COL_ID)) { + $modifiedColumns[':p' . $index++] = 'id'; + } + if ($this->isColumnModified(ProductTableMap::COL_NAME)) { + $modifiedColumns[':p' . $index++] = 'name'; + } + if ($this->isColumnModified(ProductTableMap::COL_PRICE)) { + $modifiedColumns[':p' . $index++] = 'price'; + } + if ($this->isColumnModified(ProductTableMap::COL_WIDTH)) { + $modifiedColumns[':p' . $index++] = 'width'; + } + if ($this->isColumnModified(ProductTableMap::COL_HEIGHT)) { + $modifiedColumns[':p' . $index++] = 'height'; + } + if ($this->isColumnModified(ProductTableMap::COL_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'description'; + } + + $sql = sprintf( + 'INSERT INTO product (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'id': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'name': + $stmt->bindValue($identifier, $this->name, PDO::PARAM_STR); + break; + case 'price': + $stmt->bindValue($identifier, $this->price, PDO::PARAM_STR); + break; + case 'width': + $stmt->bindValue($identifier, $this->width, PDO::PARAM_INT); + break; + case 'height': + $stmt->bindValue($identifier, $this->height, PDO::PARAM_INT); + break; + case 'description': + $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getName(); + break; + case 2: + return $this->getPrice(); + break; + case 3: + return $this->getWidth(); + break; + case 4: + return $this->getHeight(); + break; + case 5: + return $this->getDescription(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + + if (isset($alreadyDumpedObjects['Product'][$this->hashCode()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['Product'][$this->hashCode()] = true; + $keys = ProductTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getName(), + $keys[2] => $this->getPrice(), + $keys[3] => $this->getWidth(), + $keys[4] => $this->getHeight(), + $keys[5] => $this->getDescription(), + ); + $virtualColumns = $this->virtualColumns; + foreach ($virtualColumns as $key => $virtualColumn) { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->collProductCategories) { + + switch ($keyType) { + case TableMap::TYPE_CAMELNAME: + $key = 'productCategories'; + break; + case TableMap::TYPE_FIELDNAME: + $key = 'product_categories'; + break; + default: + $key = 'ProductCategories'; + } + + $result[$key] = $this->collProductCategories->toArray(null, false, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return $this|\Product + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return $this|\Product + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setName($value); + break; + case 2: + $this->setPrice($value); + break; + case 3: + $this->setWidth($value); + break; + case 4: + $this->setHeight($value); + break; + case 5: + $this->setDescription($value); + break; + } // switch() + + return $this; + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = ProductTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) { + $this->setId($arr[$keys[0]]); + } + if (array_key_exists($keys[1], $arr)) { + $this->setName($arr[$keys[1]]); + } + if (array_key_exists($keys[2], $arr)) { + $this->setPrice($arr[$keys[2]]); + } + if (array_key_exists($keys[3], $arr)) { + $this->setWidth($arr[$keys[3]]); + } + if (array_key_exists($keys[4], $arr)) { + $this->setHeight($arr[$keys[4]]); + } + if (array_key_exists($keys[5], $arr)) { + $this->setDescription($arr[$keys[5]]); + } + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * @param string $keyType The type of keys the array uses. + * + * @return $this|\Product The current object, for fluid interface + */ + public function importFrom($parser, $data, $keyType = TableMap::TYPE_PHPNAME) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + $this->fromArray($parser->toArray($data), $keyType); + + return $this; + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProductTableMap::DATABASE_NAME); + + if ($this->isColumnModified(ProductTableMap::COL_ID)) { + $criteria->add(ProductTableMap::COL_ID, $this->id); + } + if ($this->isColumnModified(ProductTableMap::COL_NAME)) { + $criteria->add(ProductTableMap::COL_NAME, $this->name); + } + if ($this->isColumnModified(ProductTableMap::COL_PRICE)) { + $criteria->add(ProductTableMap::COL_PRICE, $this->price); + } + if ($this->isColumnModified(ProductTableMap::COL_WIDTH)) { + $criteria->add(ProductTableMap::COL_WIDTH, $this->width); + } + if ($this->isColumnModified(ProductTableMap::COL_HEIGHT)) { + $criteria->add(ProductTableMap::COL_HEIGHT, $this->height); + } + if ($this->isColumnModified(ProductTableMap::COL_DESCRIPTION)) { + $criteria->add(ProductTableMap::COL_DESCRIPTION, $this->description); + } + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @throws LogicException if no primary key is defined + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = ChildProductQuery::create(); + $criteria->add(ProductTableMap::COL_ID, $this->id); + + return $criteria; + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + $validPk = null !== $this->getId(); + + $validPrimaryKeyFKs = 0; + $primaryKeyFKs = []; + + if ($validPk) { + return crc32(json_encode($this->getPrimaryKey(), JSON_UNESCAPED_UNICODE)); + } elseif ($validPrimaryKeyFKs) { + return crc32(json_encode($primaryKeyFKs, JSON_UNESCAPED_UNICODE)); + } + + return spl_object_hash($this); + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Product (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setName($this->getName()); + $copyObj->setPrice($this->getPrice()); + $copyObj->setWidth($this->getWidth()); + $copyObj->setHeight($this->getHeight()); + $copyObj->setDescription($this->getDescription()); + + if ($deepCopy) { + // important: temporarily setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + $copyObj->setNew(false); + + foreach ($this->getProductCategories() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addProductCategory($relObj->copy($deepCopy)); + } + } + + } // if ($deepCopy) + + if ($makeNew) { + $copyObj->setNew(true); + $copyObj->setId(NULL); // this is a auto-increment column, so set to default value + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Product Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + + /** + * Initializes a collection based on the name of a relation. + * Avoids crafting an 'init[$relationName]s' method name + * that wouldn't work when StandardEnglishPluralizer is used. + * + * @param string $relationName The name of the relation to initialize + * @return void + */ + public function initRelation($relationName) + { + if ('ProductCategory' == $relationName) { + return $this->initProductCategories(); + } + } + + /** + * Clears out the collProductCategories collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addProductCategories() + */ + public function clearProductCategories() + { + $this->collProductCategories = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collProductCategories collection loaded partially. + */ + public function resetPartialProductCategories($v = true) + { + $this->collProductCategoriesPartial = $v; + } + + /** + * Initializes the collProductCategories collection. + * + * By default this just sets the collProductCategories collection to an empty array (like clearcollProductCategories()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initProductCategories($overrideExisting = true) + { + if (null !== $this->collProductCategories && !$overrideExisting) { + return; + } + $this->collProductCategories = new ObjectCollection(); + $this->collProductCategories->setModel('\ProductCategory'); + } + + /** + * Gets an array of ChildProductCategory objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildProduct is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return ObjectCollection|ChildProductCategory[] List of ChildProductCategory objects + * @throws PropelException + */ + public function getProductCategories(Criteria $criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collProductCategoriesPartial && !$this->isNew(); + if (null === $this->collProductCategories || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductCategories) { + // return empty collection + $this->initProductCategories(); + } else { + $collProductCategories = ChildProductCategoryQuery::create(null, $criteria) + ->filterByProduct($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collProductCategoriesPartial && count($collProductCategories)) { + $this->initProductCategories(false); + + foreach ($collProductCategories as $obj) { + if (false == $this->collProductCategories->contains($obj)) { + $this->collProductCategories->append($obj); + } + } + + $this->collProductCategoriesPartial = true; + } + + return $collProductCategories; + } + + if ($partial && $this->collProductCategories) { + foreach ($this->collProductCategories as $obj) { + if ($obj->isNew()) { + $collProductCategories[] = $obj; + } + } + } + + $this->collProductCategories = $collProductCategories; + $this->collProductCategoriesPartial = false; + } + } + + return $this->collProductCategories; + } + + /** + * Sets a collection of ChildProductCategory objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $productCategories A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return $this|ChildProduct The current object (for fluent API support) + */ + public function setProductCategories(Collection $productCategories, ConnectionInterface $con = null) + { + /** @var ChildProductCategory[] $productCategoriesToDelete */ + $productCategoriesToDelete = $this->getProductCategories(new Criteria(), $con)->diff($productCategories); + + + //since at least one column in the foreign key is at the same time a PK + //we can not just set a PK to NULL in the lines below. We have to store + //a backup of all values, so we are able to manipulate these items based on the onDelete value later. + $this->productCategoriesScheduledForDeletion = clone $productCategoriesToDelete; + + foreach ($productCategoriesToDelete as $productCategoryRemoved) { + $productCategoryRemoved->setProduct(null); + } + + $this->collProductCategories = null; + foreach ($productCategories as $productCategory) { + $this->addProductCategory($productCategory); + } + + $this->collProductCategories = $productCategories; + $this->collProductCategoriesPartial = false; + + return $this; + } + + /** + * Returns the number of related ProductCategory objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related ProductCategory objects. + * @throws PropelException + */ + public function countProductCategories(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collProductCategoriesPartial && !$this->isNew(); + if (null === $this->collProductCategories || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductCategories) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getProductCategories()); + } + + $query = ChildProductCategoryQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByProduct($this) + ->count($con); + } + + return count($this->collProductCategories); + } + + /** + * Method called to associate a ChildProductCategory object to this object + * through the ChildProductCategory foreign key attribute. + * + * @param ChildProductCategory $l ChildProductCategory + * @return $this|\Product The current object (for fluent API support) + */ + public function addProductCategory(ChildProductCategory $l) + { + if ($this->collProductCategories === null) { + $this->initProductCategories(); + $this->collProductCategoriesPartial = true; + } + + if (!$this->collProductCategories->contains($l)) { + $this->doAddProductCategory($l); + } + + return $this; + } + + /** + * @param ChildProductCategory $productCategory The ChildProductCategory object to add. + */ + protected function doAddProductCategory(ChildProductCategory $productCategory) + { + $this->collProductCategories[]= $productCategory; + $productCategory->setProduct($this); + } + + /** + * @param ChildProductCategory $productCategory The ChildProductCategory object to remove. + * @return $this|ChildProduct The current object (for fluent API support) + */ + public function removeProductCategory(ChildProductCategory $productCategory) + { + if ($this->getProductCategories()->contains($productCategory)) { + $pos = $this->collProductCategories->search($productCategory); + $this->collProductCategories->remove($pos); + if (null === $this->productCategoriesScheduledForDeletion) { + $this->productCategoriesScheduledForDeletion = clone $this->collProductCategories; + $this->productCategoriesScheduledForDeletion->clear(); + } + $this->productCategoriesScheduledForDeletion[]= clone $productCategory; + $productCategory->setProduct(null); + } + + return $this; + } + + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this Product is new, it will return + * an empty collection; or if this Product has previously + * been saved, it will retrieve related ProductCategories from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in Product. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) + * @return ObjectCollection|ChildProductCategory[] List of ChildProductCategory objects + */ + public function getProductCategoriesJoinCategory(Criteria $criteria = null, ConnectionInterface $con = null, $joinBehavior = Criteria::LEFT_JOIN) + { + $query = ChildProductCategoryQuery::create(null, $criteria); + $query->joinWith('Category', $joinBehavior); + + return $this->getProductCategories($query, $con); + } + + /** + * Clears out the collCategories collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addCategories() + */ + public function clearCategories() + { + $this->collCategories = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Initializes the collCategories crossRef collection. + * + * By default this just sets the collCategories collection to an empty collection (like clearCategories()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @return void + */ + public function initCategories() + { + $this->collCategories = new ObjectCollection(); + $this->collCategoriesPartial = true; + + $this->collCategories->setModel('\Category'); + } + + /** + * Checks if the collCategories collection is loaded. + * + * @return bool + */ + public function isCategoriesLoaded() + { + return null !== $this->collCategories; + } + + /** + * Gets a collection of ChildCategory objects related by a many-to-many relationship + * to the current object by way of the product_category cross-reference table. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildProduct is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria Optional query object to filter the query + * @param ConnectionInterface $con Optional connection object + * + * @return ObjectCollection|ChildCategory[] List of ChildCategory objects + */ + public function getCategories(Criteria $criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collCategoriesPartial && !$this->isNew(); + if (null === $this->collCategories || null !== $criteria || $partial) { + if ($this->isNew()) { + // return empty collection + if (null === $this->collCategories) { + $this->initCategories(); + } + } else { + + $query = ChildCategoryQuery::create(null, $criteria) + ->filterByProduct($this); + $collCategories = $query->find($con); + if (null !== $criteria) { + return $collCategories; + } + + if ($partial && $this->collCategories) { + //make sure that already added objects gets added to the list of the database. + foreach ($this->collCategories as $obj) { + if (!$collCategories->contains($obj)) { + $collCategories[] = $obj; + } + } + } + + $this->collCategories = $collCategories; + $this->collCategoriesPartial = false; + } + } + + return $this->collCategories; + } + + /** + * Sets a collection of Category objects related by a many-to-many relationship + * to the current object by way of the product_category cross-reference table. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $categories A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return $this|ChildProduct The current object (for fluent API support) + */ + public function setCategories(Collection $categories, ConnectionInterface $con = null) + { + $this->clearCategories(); + $currentCategories = $this->getCategories(); + + $categoriesScheduledForDeletion = $currentCategories->diff($categories); + + foreach ($categoriesScheduledForDeletion as $toDelete) { + $this->removeCategory($toDelete); + } + + foreach ($categories as $category) { + if (!$currentCategories->contains($category)) { + $this->doAddCategory($category); + } + } + + $this->collCategoriesPartial = false; + $this->collCategories = $categories; + + return $this; + } + + /** + * Gets the number of Category objects related by a many-to-many relationship + * to the current object by way of the product_category cross-reference table. + * + * @param Criteria $criteria Optional query object to filter the query + * @param boolean $distinct Set to true to force count distinct + * @param ConnectionInterface $con Optional connection object + * + * @return int the number of related Category objects + */ + public function countCategories(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collCategoriesPartial && !$this->isNew(); + if (null === $this->collCategories || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collCategories) { + return 0; + } else { + + if ($partial && !$criteria) { + return count($this->getCategories()); + } + + $query = ChildCategoryQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByProduct($this) + ->count($con); + } + } else { + return count($this->collCategories); + } + } + + /** + * Associate a ChildCategory to this object + * through the product_category cross reference table. + * + * @param ChildCategory $category + * @return ChildProduct The current object (for fluent API support) + */ + public function addCategory(ChildCategory $category) + { + if ($this->collCategories === null) { + $this->initCategories(); + } + + if (!$this->getCategories()->contains($category)) { + // only add it if the **same** object is not already associated + $this->collCategories->push($category); + $this->doAddCategory($category); + } + + return $this; + } + + /** + * + * @param ChildCategory $category + */ + protected function doAddCategory(ChildCategory $category) + { + $productCategory = new ChildProductCategory(); + + $productCategory->setCategory($category); + + $productCategory->setProduct($this); + + $this->addProductCategory($productCategory); + + // set the back reference to this object directly as using provided method either results + // in endless loop or in multiple relations + if (!$category->isProductsLoaded()) { + $category->initProducts(); + $category->getProducts()->push($this); + } elseif (!$category->getProducts()->contains($this)) { + $category->getProducts()->push($this); + } + + } + + /** + * Remove category of this object + * through the product_category cross reference table. + * + * @param ChildCategory $category + * @return ChildProduct The current object (for fluent API support) + */ + public function removeCategory(ChildCategory $category) + { + if ($this->getCategories()->contains($category)) { $productCategory = new ChildProductCategory(); + + $productCategory->setCategory($category); + if ($category->isProductsLoaded()) { + //remove the back reference if available + $category->getProducts()->removeObject($this); + } + + $productCategory->setProduct($this); + $this->removeProductCategory(clone $productCategory); + $productCategory->clear(); + + $this->collCategories->remove($this->collCategories->search($category)); + + if (null === $this->categoriesScheduledForDeletion) { + $this->categoriesScheduledForDeletion = clone $this->collCategories; + $this->categoriesScheduledForDeletion->clear(); + } + + $this->categoriesScheduledForDeletion->push($category); + } + + + return $this; + } + + /** + * Clears the current object, sets all attributes to their default values and removes + * outgoing references as well as back-references (from other objects to this one. Results probably in a database + * change of those foreign objects when you call `save` there). + */ + public function clear() + { + $this->id = null; + $this->name = null; + $this->price = null; + $this->width = null; + $this->height = null; + $this->description = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references and back-references to other model objects or collections of model objects. + * + * This method is used to reset all php object references (not the actual reference in the database). + * Necessary for object serialisation. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + if ($this->collProductCategories) { + foreach ($this->collProductCategories as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collCategories) { + foreach ($this->collCategories as $o) { + $o->clearAllReferences($deep); + } + } + } // if ($deep) + + $this->collProductCategories = null; + $this->collCategories = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(ProductTableMap::DEFAULT_STRING_FORMAT); + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/generated-classes/Base/ProductCategory.php b/generated-classes/Base/ProductCategory.php new file mode 100644 index 0000000..9e14779 --- /dev/null +++ b/generated-classes/Base/ProductCategory.php @@ -0,0 +1,1328 @@ +modifiedColumns; + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return $this->modifiedColumns && isset($this->modifiedColumns[$col]); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return $this->modifiedColumns ? array_keys($this->modifiedColumns) : []; + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return boolean true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + if (isset($this->modifiedColumns[$col])) { + unset($this->modifiedColumns[$col]); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another ProductCategory instance. If + * obj is an instance of ProductCategory, delegates to + * equals(ProductCategory). Otherwise, returns false. + * + * @param mixed $obj The object to compare to. + * @return boolean Whether equal to the object specified. + */ + public function equals($obj) + { + if (!$obj instanceof static) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @param string $name The virtual column name + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @param string $name The virtual column name + * @return mixed + * + * @throws PropelException + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return $this|ProductCategory The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [product_id] column value. + * + * @return int + */ + public function getProductId() + { + return $this->product_id; + } + + /** + * Get the [category_id] column value. + * + * @return int + */ + public function getCategoryId() + { + return $this->category_id; + } + + /** + * Set the value of [product_id] column. + * + * @param int $v new value + * @return $this|\ProductCategory The current object (for fluent API support) + */ + public function setProductId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->product_id !== $v) { + $this->product_id = $v; + $this->modifiedColumns[ProductCategoryTableMap::COL_PRODUCT_ID] = true; + } + + if ($this->aProduct !== null && $this->aProduct->getId() !== $v) { + $this->aProduct = null; + } + + return $this; + } // setProductId() + + /** + * Set the value of [category_id] column. + * + * @param int $v new value + * @return $this|\ProductCategory The current object (for fluent API support) + */ + public function setCategoryId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->category_id !== $v) { + $this->category_id = $v; + $this->modifiedColumns[ProductCategoryTableMap::COL_CATEGORY_ID] = true; + } + + if ($this->aCategory !== null && $this->aCategory->getId() !== $v) { + $this->aCategory = null; + } + + return $this; + } // setCategoryId() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ProductCategoryTableMap::translateFieldName('ProductId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->product_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ProductCategoryTableMap::translateFieldName('CategoryId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->category_id = (null !== $col) ? (int) $col : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 2; // 2 = ProductCategoryTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException(sprintf('Error populating %s object', '\\ProductCategory'), 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aProduct !== null && $this->product_id !== $this->aProduct->getId()) { + $this->aProduct = null; + } + if ($this->aCategory !== null && $this->category_id !== $this->aCategory->getId()) { + $this->aCategory = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductCategoryTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildProductCategoryQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aCategory = null; + $this->aProduct = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see ProductCategory::setDeleted() + * @see ProductCategory::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductCategoryTableMap::DATABASE_NAME); + } + + $con->transaction(function () use ($con) { + $deleteQuery = ChildProductCategoryQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $this->setDeleted(true); + } + }); + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductCategoryTableMap::DATABASE_NAME); + } + + return $con->transaction(function () use ($con) { + $isInsert = $this->isNew(); + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + } else { + $ret = $ret && $this->preUpdate($con); + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + ProductCategoryTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + + return $affectedRows; + }); + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aCategory !== null) { + if ($this->aCategory->isModified() || $this->aCategory->isNew()) { + $affectedRows += $this->aCategory->save($con); + } + $this->setCategory($this->aCategory); + } + + if ($this->aProduct !== null) { + if ($this->aProduct->isModified() || $this->aProduct->isNew()) { + $affectedRows += $this->aProduct->save($con); + } + $this->setProduct($this->aProduct); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + $affectedRows += 1; + } else { + $affectedRows += $this->doUpdate($con); + } + $this->resetModified(); + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(ProductCategoryTableMap::COL_PRODUCT_ID)) { + $modifiedColumns[':p' . $index++] = 'product_id'; + } + if ($this->isColumnModified(ProductCategoryTableMap::COL_CATEGORY_ID)) { + $modifiedColumns[':p' . $index++] = 'category_id'; + } + + $sql = sprintf( + 'INSERT INTO product_category (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'product_id': + $stmt->bindValue($identifier, $this->product_id, PDO::PARAM_INT); + break; + case 'category_id': + $stmt->bindValue($identifier, $this->category_id, PDO::PARAM_INT); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductCategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getProductId(); + break; + case 1: + return $this->getCategoryId(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + + if (isset($alreadyDumpedObjects['ProductCategory'][$this->hashCode()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['ProductCategory'][$this->hashCode()] = true; + $keys = ProductCategoryTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getProductId(), + $keys[1] => $this->getCategoryId(), + ); + $virtualColumns = $this->virtualColumns; + foreach ($virtualColumns as $key => $virtualColumn) { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aCategory) { + + switch ($keyType) { + case TableMap::TYPE_CAMELNAME: + $key = 'category'; + break; + case TableMap::TYPE_FIELDNAME: + $key = 'category'; + break; + default: + $key = 'Category'; + } + + $result[$key] = $this->aCategory->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + if (null !== $this->aProduct) { + + switch ($keyType) { + case TableMap::TYPE_CAMELNAME: + $key = 'product'; + break; + case TableMap::TYPE_FIELDNAME: + $key = 'product'; + break; + default: + $key = 'Product'; + } + + $result[$key] = $this->aProduct->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return $this|\ProductCategory + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductCategoryTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return $this|\ProductCategory + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setProductId($value); + break; + case 1: + $this->setCategoryId($value); + break; + } // switch() + + return $this; + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = ProductCategoryTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) { + $this->setProductId($arr[$keys[0]]); + } + if (array_key_exists($keys[1], $arr)) { + $this->setCategoryId($arr[$keys[1]]); + } + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * @param string $keyType The type of keys the array uses. + * + * @return $this|\ProductCategory The current object, for fluid interface + */ + public function importFrom($parser, $data, $keyType = TableMap::TYPE_PHPNAME) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + $this->fromArray($parser->toArray($data), $keyType); + + return $this; + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProductCategoryTableMap::DATABASE_NAME); + + if ($this->isColumnModified(ProductCategoryTableMap::COL_PRODUCT_ID)) { + $criteria->add(ProductCategoryTableMap::COL_PRODUCT_ID, $this->product_id); + } + if ($this->isColumnModified(ProductCategoryTableMap::COL_CATEGORY_ID)) { + $criteria->add(ProductCategoryTableMap::COL_CATEGORY_ID, $this->category_id); + } + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @throws LogicException if no primary key is defined + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = ChildProductCategoryQuery::create(); + $criteria->add(ProductCategoryTableMap::COL_PRODUCT_ID, $this->product_id); + $criteria->add(ProductCategoryTableMap::COL_CATEGORY_ID, $this->category_id); + + return $criteria; + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + $validPk = null !== $this->getProductId() && + null !== $this->getCategoryId(); + + $validPrimaryKeyFKs = 2; + $primaryKeyFKs = []; + + //relation product_category_ibfk_1 to table category + if ($this->aCategory && $hash = spl_object_hash($this->aCategory)) { + $primaryKeyFKs[] = $hash; + } else { + $validPrimaryKeyFKs = false; + } + + //relation product_category_ibfk_2 to table product + if ($this->aProduct && $hash = spl_object_hash($this->aProduct)) { + $primaryKeyFKs[] = $hash; + } else { + $validPrimaryKeyFKs = false; + } + + if ($validPk) { + return crc32(json_encode($this->getPrimaryKey(), JSON_UNESCAPED_UNICODE)); + } elseif ($validPrimaryKeyFKs) { + return crc32(json_encode($primaryKeyFKs, JSON_UNESCAPED_UNICODE)); + } + + return spl_object_hash($this); + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + $pks[0] = $this->getProductId(); + $pks[1] = $this->getCategoryId(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + $this->setProductId($keys[0]); + $this->setCategoryId($keys[1]); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + return (null === $this->getProductId()) && (null === $this->getCategoryId()); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \ProductCategory (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setProductId($this->getProductId()); + $copyObj->setCategoryId($this->getCategoryId()); + if ($makeNew) { + $copyObj->setNew(true); + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \ProductCategory Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildCategory object. + * + * @param ChildCategory $v + * @return $this|\ProductCategory The current object (for fluent API support) + * @throws PropelException + */ + public function setCategory(ChildCategory $v = null) + { + if ($v === null) { + $this->setCategoryId(NULL); + } else { + $this->setCategoryId($v->getId()); + } + + $this->aCategory = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildCategory object, it will not be re-added. + if ($v !== null) { + $v->addProductCategory($this); + } + + + return $this; + } + + + /** + * Get the associated ChildCategory object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildCategory The associated ChildCategory object. + * @throws PropelException + */ + public function getCategory(ConnectionInterface $con = null) + { + if ($this->aCategory === null && ($this->category_id !== null)) { + $this->aCategory = ChildCategoryQuery::create()->findPk($this->category_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aCategory->addProductCategories($this); + */ + } + + return $this->aCategory; + } + + /** + * Declares an association between this object and a ChildProduct object. + * + * @param ChildProduct $v + * @return $this|\ProductCategory The current object (for fluent API support) + * @throws PropelException + */ + public function setProduct(ChildProduct $v = null) + { + if ($v === null) { + $this->setProductId(NULL); + } else { + $this->setProductId($v->getId()); + } + + $this->aProduct = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildProduct object, it will not be re-added. + if ($v !== null) { + $v->addProductCategory($this); + } + + + return $this; + } + + + /** + * Get the associated ChildProduct object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildProduct The associated ChildProduct object. + * @throws PropelException + */ + public function getProduct(ConnectionInterface $con = null) + { + if ($this->aProduct === null && ($this->product_id !== null)) { + $this->aProduct = ChildProductQuery::create()->findPk($this->product_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aProduct->addProductCategories($this); + */ + } + + return $this->aProduct; + } + + /** + * Clears the current object, sets all attributes to their default values and removes + * outgoing references as well as back-references (from other objects to this one. Results probably in a database + * change of those foreign objects when you call `save` there). + */ + public function clear() + { + if (null !== $this->aCategory) { + $this->aCategory->removeProductCategory($this); + } + if (null !== $this->aProduct) { + $this->aProduct->removeProductCategory($this); + } + $this->product_id = null; + $this->category_id = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references and back-references to other model objects or collections of model objects. + * + * This method is used to reset all php object references (not the actual reference in the database). + * Necessary for object serialisation. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + } // if ($deep) + + $this->aCategory = null; + $this->aProduct = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(ProductCategoryTableMap::DEFAULT_STRING_FORMAT); + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/generated-classes/Base/ProductCategoryQuery.php b/generated-classes/Base/ProductCategoryQuery.php new file mode 100644 index 0000000..b2827c4 --- /dev/null +++ b/generated-classes/Base/ProductCategoryQuery.php @@ -0,0 +1,571 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(array(12, 34), $con); + * + * + * @param array[$product_id, $category_id] $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildProductCategory|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, ConnectionInterface $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = ProductCategoryTableMap::getInstanceFromPool(serialize(array((string) $key[0], (string) $key[1]))))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductCategoryTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @throws \Propel\Runtime\Exception\PropelException + * + * @return ChildProductCategory A model object, or null if the key is not found + */ + protected function findPkSimple($key, ConnectionInterface $con) + { + $sql = 'SELECT product_id, category_id FROM product_category WHERE product_id = :p0 AND category_id = :p1'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); + $stmt->bindValue(':p1', $key[1], PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + /** @var ChildProductCategory $obj */ + $obj = new ChildProductCategory(); + $obj->hydrate($row); + ProductCategoryTableMap::addInstanceToPool($obj, serialize(array((string) $key[0], (string) $key[1]))); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildProductCategory|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, ConnectionInterface $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(array(12, 56), array(832, 123), array(123, 456)), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return $this|ChildProductCategoryQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + $this->addUsingAlias(ProductCategoryTableMap::COL_PRODUCT_ID, $key[0], Criteria::EQUAL); + $this->addUsingAlias(ProductCategoryTableMap::COL_CATEGORY_ID, $key[1], Criteria::EQUAL); + + return $this; + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return $this|ChildProductCategoryQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + if (empty($keys)) { + return $this->add(null, '1<>1', Criteria::CUSTOM); + } + foreach ($keys as $key) { + $cton0 = $this->getNewCriterion(ProductCategoryTableMap::COL_PRODUCT_ID, $key[0], Criteria::EQUAL); + $cton1 = $this->getNewCriterion(ProductCategoryTableMap::COL_CATEGORY_ID, $key[1], Criteria::EQUAL); + $cton0->addAnd($cton1); + $this->addOr($cton0); + } + + return $this; + } + + /** + * Filter the query on the product_id column + * + * Example usage: + * + * $query->filterByProductId(1234); // WHERE product_id = 1234 + * $query->filterByProductId(array(12, 34)); // WHERE product_id IN (12, 34) + * $query->filterByProductId(array('min' => 12)); // WHERE product_id > 12 + * + * + * @see filterByProduct() + * + * @param mixed $productId The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductCategoryQuery The current query, for fluid interface + */ + public function filterByProductId($productId = null, $comparison = null) + { + if (is_array($productId)) { + $useMinMax = false; + if (isset($productId['min'])) { + $this->addUsingAlias(ProductCategoryTableMap::COL_PRODUCT_ID, $productId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($productId['max'])) { + $this->addUsingAlias(ProductCategoryTableMap::COL_PRODUCT_ID, $productId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductCategoryTableMap::COL_PRODUCT_ID, $productId, $comparison); + } + + /** + * Filter the query on the category_id column + * + * Example usage: + * + * $query->filterByCategoryId(1234); // WHERE category_id = 1234 + * $query->filterByCategoryId(array(12, 34)); // WHERE category_id IN (12, 34) + * $query->filterByCategoryId(array('min' => 12)); // WHERE category_id > 12 + * + * + * @see filterByCategory() + * + * @param mixed $categoryId The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductCategoryQuery The current query, for fluid interface + */ + public function filterByCategoryId($categoryId = null, $comparison = null) + { + if (is_array($categoryId)) { + $useMinMax = false; + if (isset($categoryId['min'])) { + $this->addUsingAlias(ProductCategoryTableMap::COL_CATEGORY_ID, $categoryId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($categoryId['max'])) { + $this->addUsingAlias(ProductCategoryTableMap::COL_CATEGORY_ID, $categoryId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductCategoryTableMap::COL_CATEGORY_ID, $categoryId, $comparison); + } + + /** + * Filter the query by a related \Category object + * + * @param \Category|ObjectCollection $category The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @throws \Propel\Runtime\Exception\PropelException + * + * @return ChildProductCategoryQuery The current query, for fluid interface + */ + public function filterByCategory($category, $comparison = null) + { + if ($category instanceof \Category) { + return $this + ->addUsingAlias(ProductCategoryTableMap::COL_CATEGORY_ID, $category->getId(), $comparison); + } elseif ($category instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(ProductCategoryTableMap::COL_CATEGORY_ID, $category->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByCategory() only accepts arguments of type \Category or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Category relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return $this|ChildProductCategoryQuery The current query, for fluid interface + */ + public function joinCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Category'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Category'); + } + + return $this; + } + + /** + * Use the Category relation Category object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \CategoryQuery A secondary query class using the current class as primary query + */ + public function useCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinCategory($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Category', '\CategoryQuery'); + } + + /** + * Filter the query by a related \Product object + * + * @param \Product|ObjectCollection $product The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @throws \Propel\Runtime\Exception\PropelException + * + * @return ChildProductCategoryQuery The current query, for fluid interface + */ + public function filterByProduct($product, $comparison = null) + { + if ($product instanceof \Product) { + return $this + ->addUsingAlias(ProductCategoryTableMap::COL_PRODUCT_ID, $product->getId(), $comparison); + } elseif ($product instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(ProductCategoryTableMap::COL_PRODUCT_ID, $product->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByProduct() only accepts arguments of type \Product or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Product relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return $this|ChildProductCategoryQuery The current query, for fluid interface + */ + public function joinProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Product'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Product'); + } + + return $this; + } + + /** + * Use the Product relation Product object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \ProductQuery A secondary query class using the current class as primary query + */ + public function useProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinProduct($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Product', '\ProductQuery'); + } + + /** + * Exclude object from result + * + * @param ChildProductCategory $productCategory Object to remove from the list of results + * + * @return $this|ChildProductCategoryQuery The current query, for fluid interface + */ + public function prune($productCategory = null) + { + if ($productCategory) { + $this->addCond('pruneCond0', $this->getAliasedColName(ProductCategoryTableMap::COL_PRODUCT_ID), $productCategory->getProductId(), Criteria::NOT_EQUAL); + $this->addCond('pruneCond1', $this->getAliasedColName(ProductCategoryTableMap::COL_CATEGORY_ID), $productCategory->getCategoryId(), Criteria::NOT_EQUAL); + $this->combine(array('pruneCond0', 'pruneCond1'), Criteria::LOGICAL_OR); + } + + return $this; + } + + /** + * Deletes all rows from the product_category table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductCategoryTableMap::DATABASE_NAME); + } + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con) { + $affectedRows = 0; // initialize var to track total num of affected rows + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + ProductCategoryTableMap::clearInstancePool(); + ProductCategoryTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + + /** + * Performs a DELETE on the database based on the current ModelCriteria + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductCategoryTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(ProductCategoryTableMap::DATABASE_NAME); + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con, $criteria) { + $affectedRows = 0; // initialize var to track total num of affected rows + + ProductCategoryTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + ProductCategoryTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + +} // ProductCategoryQuery diff --git a/generated-classes/Base/ProductQuery.php b/generated-classes/Base/ProductQuery.php new file mode 100644 index 0000000..0665619 --- /dev/null +++ b/generated-classes/Base/ProductQuery.php @@ -0,0 +1,645 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildProduct|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, ConnectionInterface $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = ProductTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @throws \Propel\Runtime\Exception\PropelException + * + * @return ChildProduct A model object, or null if the key is not found + */ + protected function findPkSimple($key, ConnectionInterface $con) + { + $sql = 'SELECT id, name, price, width, height, description FROM product WHERE id = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + /** @var ChildProduct $obj */ + $obj = new ChildProduct(); + $obj->hydrate($row); + ProductTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildProduct|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, ConnectionInterface $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(ProductTableMap::COL_ID, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(ProductTableMap::COL_ID, $keys, Criteria::IN); + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @param mixed $id The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(ProductTableMap::COL_ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(ProductTableMap::COL_ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductTableMap::COL_ID, $id, $comparison); + } + + /** + * Filter the query on the name column + * + * Example usage: + * + * $query->filterByName('fooValue'); // WHERE name = 'fooValue' + * $query->filterByName('%fooValue%'); // WHERE name LIKE '%fooValue%' + * + * + * @param string $name The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterByName($name = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($name)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $name)) { + $name = str_replace('*', '%', $name); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductTableMap::COL_NAME, $name, $comparison); + } + + /** + * Filter the query on the price column + * + * Example usage: + * + * $query->filterByPrice(1234); // WHERE price = 1234 + * $query->filterByPrice(array(12, 34)); // WHERE price IN (12, 34) + * $query->filterByPrice(array('min' => 12)); // WHERE price > 12 + * + * + * @param mixed $price The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterByPrice($price = null, $comparison = null) + { + if (is_array($price)) { + $useMinMax = false; + if (isset($price['min'])) { + $this->addUsingAlias(ProductTableMap::COL_PRICE, $price['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($price['max'])) { + $this->addUsingAlias(ProductTableMap::COL_PRICE, $price['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductTableMap::COL_PRICE, $price, $comparison); + } + + /** + * Filter the query on the width column + * + * Example usage: + * + * $query->filterByWidth(1234); // WHERE width = 1234 + * $query->filterByWidth(array(12, 34)); // WHERE width IN (12, 34) + * $query->filterByWidth(array('min' => 12)); // WHERE width > 12 + * + * + * @param mixed $width The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterByWidth($width = null, $comparison = null) + { + if (is_array($width)) { + $useMinMax = false; + if (isset($width['min'])) { + $this->addUsingAlias(ProductTableMap::COL_WIDTH, $width['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($width['max'])) { + $this->addUsingAlias(ProductTableMap::COL_WIDTH, $width['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductTableMap::COL_WIDTH, $width, $comparison); + } + + /** + * Filter the query on the height column + * + * Example usage: + * + * $query->filterByHeight(1234); // WHERE height = 1234 + * $query->filterByHeight(array(12, 34)); // WHERE height IN (12, 34) + * $query->filterByHeight(array('min' => 12)); // WHERE height > 12 + * + * + * @param mixed $height The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterByHeight($height = null, $comparison = null) + { + if (is_array($height)) { + $useMinMax = false; + if (isset($height['min'])) { + $this->addUsingAlias(ProductTableMap::COL_HEIGHT, $height['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($height['max'])) { + $this->addUsingAlias(ProductTableMap::COL_HEIGHT, $height['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductTableMap::COL_HEIGHT, $height, $comparison); + } + + /** + * Filter the query on the description column + * + * Example usage: + * + * $query->filterByDescription('fooValue'); // WHERE description = 'fooValue' + * $query->filterByDescription('%fooValue%'); // WHERE description LIKE '%fooValue%' + * + * + * @param string $description The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function filterByDescription($description = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($description)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $description)) { + $description = str_replace('*', '%', $description); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductTableMap::COL_DESCRIPTION, $description, $comparison); + } + + /** + * Filter the query by a related \ProductCategory object + * + * @param \ProductCategory|ObjectCollection $productCategory the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductQuery The current query, for fluid interface + */ + public function filterByProductCategory($productCategory, $comparison = null) + { + if ($productCategory instanceof \ProductCategory) { + return $this + ->addUsingAlias(ProductTableMap::COL_ID, $productCategory->getProductId(), $comparison); + } elseif ($productCategory instanceof ObjectCollection) { + return $this + ->useProductCategoryQuery() + ->filterByPrimaryKeys($productCategory->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByProductCategory() only accepts arguments of type \ProductCategory or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the ProductCategory relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function joinProductCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('ProductCategory'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'ProductCategory'); + } + + return $this; + } + + /** + * Use the ProductCategory relation ProductCategory object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \ProductCategoryQuery A secondary query class using the current class as primary query + */ + public function useProductCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinProductCategory($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ProductCategory', '\ProductCategoryQuery'); + } + + /** + * Filter the query by a related Category object + * using the product_category table as cross reference + * + * @param Category $category the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductQuery The current query, for fluid interface + */ + public function filterByCategory($category, $comparison = Criteria::EQUAL) + { + return $this + ->useProductCategoryQuery() + ->filterByCategory($category, $comparison) + ->endUse(); + } + + /** + * Exclude object from result + * + * @param ChildProduct $product Object to remove from the list of results + * + * @return $this|ChildProductQuery The current query, for fluid interface + */ + public function prune($product = null) + { + if ($product) { + $this->addUsingAlias(ProductTableMap::COL_ID, $product->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the product table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductTableMap::DATABASE_NAME); + } + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con) { + $affectedRows = 0; // initialize var to track total num of affected rows + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + ProductTableMap::clearInstancePool(); + ProductTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + + /** + * Performs a DELETE on the database based on the current ModelCriteria + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(ProductTableMap::DATABASE_NAME); + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con, $criteria) { + $affectedRows = 0; // initialize var to track total num of affected rows + + ProductTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + ProductTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + +} // ProductQuery diff --git a/generated-classes/Base/User.php b/generated-classes/Base/User.php new file mode 100644 index 0000000..0bec834 --- /dev/null +++ b/generated-classes/Base/User.php @@ -0,0 +1,1174 @@ +modifiedColumns; + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return $this->modifiedColumns && isset($this->modifiedColumns[$col]); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return $this->modifiedColumns ? array_keys($this->modifiedColumns) : []; + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return boolean true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + if (isset($this->modifiedColumns[$col])) { + unset($this->modifiedColumns[$col]); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another User instance. If + * obj is an instance of User, delegates to + * equals(User). Otherwise, returns false. + * + * @param mixed $obj The object to compare to. + * @return boolean Whether equal to the object specified. + */ + public function equals($obj) + { + if (!$obj instanceof static) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @param string $name The virtual column name + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @param string $name The virtual column name + * @return mixed + * + * @throws PropelException + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return $this|User The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [username] column value. + * + * @return string + */ + public function getUsername() + { + return $this->username; + } + + /** + * Get the [password] column value. + * + * @return string + */ + public function getPassword() + { + return $this->password; + } + + /** + * Get the [salt] column value. + * + * @return string + */ + public function getSalt() + { + return $this->salt; + } + + /** + * Set the value of [username] column. + * + * @param string $v new value + * @return $this|\User The current object (for fluent API support) + */ + public function setUsername($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->username !== $v) { + $this->username = $v; + $this->modifiedColumns[UserTableMap::COL_USERNAME] = true; + } + + return $this; + } // setUsername() + + /** + * Set the value of [password] column. + * + * @param string $v new value + * @return $this|\User The current object (for fluent API support) + */ + public function setPassword($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->password !== $v) { + $this->password = $v; + $this->modifiedColumns[UserTableMap::COL_PASSWORD] = true; + } + + return $this; + } // setPassword() + + /** + * Set the value of [salt] column. + * + * @param string $v new value + * @return $this|\User The current object (for fluent API support) + */ + public function setSalt($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->salt !== $v) { + $this->salt = $v; + $this->modifiedColumns[UserTableMap::COL_SALT] = true; + } + + return $this; + } // setSalt() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : UserTableMap::translateFieldName('Username', TableMap::TYPE_PHPNAME, $indexType)]; + $this->username = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : UserTableMap::translateFieldName('Password', TableMap::TYPE_PHPNAME, $indexType)]; + $this->password = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : UserTableMap::translateFieldName('Salt', TableMap::TYPE_PHPNAME, $indexType)]; + $this->salt = (null !== $col) ? (string) $col : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 3; // 3 = UserTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException(sprintf('Error populating %s object', '\\User'), 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(UserTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildUserQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see User::setDeleted() + * @see User::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(UserTableMap::DATABASE_NAME); + } + + $con->transaction(function () use ($con) { + $deleteQuery = ChildUserQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $this->setDeleted(true); + } + }); + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(UserTableMap::DATABASE_NAME); + } + + return $con->transaction(function () use ($con) { + $isInsert = $this->isNew(); + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + } else { + $ret = $ret && $this->preUpdate($con); + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + UserTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + + return $affectedRows; + }); + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + $affectedRows += 1; + } else { + $affectedRows += $this->doUpdate($con); + } + $this->resetModified(); + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(UserTableMap::COL_USERNAME)) { + $modifiedColumns[':p' . $index++] = 'username'; + } + if ($this->isColumnModified(UserTableMap::COL_PASSWORD)) { + $modifiedColumns[':p' . $index++] = 'password'; + } + if ($this->isColumnModified(UserTableMap::COL_SALT)) { + $modifiedColumns[':p' . $index++] = 'salt'; + } + + $sql = sprintf( + 'INSERT INTO user (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'username': + $stmt->bindValue($identifier, $this->username, PDO::PARAM_STR); + break; + case 'password': + $stmt->bindValue($identifier, $this->password, PDO::PARAM_STR); + break; + case 'salt': + $stmt->bindValue($identifier, $this->salt, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = UserTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getUsername(); + break; + case 1: + return $this->getPassword(); + break; + case 2: + return $this->getSalt(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array()) + { + + if (isset($alreadyDumpedObjects['User'][$this->hashCode()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['User'][$this->hashCode()] = true; + $keys = UserTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getUsername(), + $keys[1] => $this->getPassword(), + $keys[2] => $this->getSalt(), + ); + $virtualColumns = $this->virtualColumns; + foreach ($virtualColumns as $key => $virtualColumn) { + $result[$key] = $virtualColumn; + } + + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return $this|\User + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = UserTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return $this|\User + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setUsername($value); + break; + case 1: + $this->setPassword($value); + break; + case 2: + $this->setSalt($value); + break; + } // switch() + + return $this; + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = UserTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) { + $this->setUsername($arr[$keys[0]]); + } + if (array_key_exists($keys[1], $arr)) { + $this->setPassword($arr[$keys[1]]); + } + if (array_key_exists($keys[2], $arr)) { + $this->setSalt($arr[$keys[2]]); + } + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * @param string $keyType The type of keys the array uses. + * + * @return $this|\User The current object, for fluid interface + */ + public function importFrom($parser, $data, $keyType = TableMap::TYPE_PHPNAME) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + $this->fromArray($parser->toArray($data), $keyType); + + return $this; + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(UserTableMap::DATABASE_NAME); + + if ($this->isColumnModified(UserTableMap::COL_USERNAME)) { + $criteria->add(UserTableMap::COL_USERNAME, $this->username); + } + if ($this->isColumnModified(UserTableMap::COL_PASSWORD)) { + $criteria->add(UserTableMap::COL_PASSWORD, $this->password); + } + if ($this->isColumnModified(UserTableMap::COL_SALT)) { + $criteria->add(UserTableMap::COL_SALT, $this->salt); + } + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @throws LogicException if no primary key is defined + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = ChildUserQuery::create(); + $criteria->add(UserTableMap::COL_USERNAME, $this->username); + + return $criteria; + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + $validPk = null !== $this->getUsername(); + + $validPrimaryKeyFKs = 0; + $primaryKeyFKs = []; + + if ($validPk) { + return crc32(json_encode($this->getPrimaryKey(), JSON_UNESCAPED_UNICODE)); + } elseif ($validPrimaryKeyFKs) { + return crc32(json_encode($primaryKeyFKs, JSON_UNESCAPED_UNICODE)); + } + + return spl_object_hash($this); + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getUsername(); + } + + /** + * Generic method to set the primary key (username column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setUsername($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + return null === $this->getUsername(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \User (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setUsername($this->getUsername()); + $copyObj->setPassword($this->getPassword()); + $copyObj->setSalt($this->getSalt()); + if ($makeNew) { + $copyObj->setNew(true); + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \User Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Clears the current object, sets all attributes to their default values and removes + * outgoing references as well as back-references (from other objects to this one. Results probably in a database + * change of those foreign objects when you call `save` there). + */ + public function clear() + { + $this->username = null; + $this->password = null; + $this->salt = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references and back-references to other model objects or collections of model objects. + * + * This method is used to reset all php object references (not the actual reference in the database). + * Necessary for object serialisation. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + } // if ($deep) + + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(UserTableMap::DEFAULT_STRING_FORMAT); + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/generated-classes/Base/UserQuery.php b/generated-classes/Base/UserQuery.php new file mode 100644 index 0000000..dba623b --- /dev/null +++ b/generated-classes/Base/UserQuery.php @@ -0,0 +1,398 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildUser|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, ConnectionInterface $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = UserTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(UserTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @throws \Propel\Runtime\Exception\PropelException + * + * @return ChildUser A model object, or null if the key is not found + */ + protected function findPkSimple($key, ConnectionInterface $con) + { + $sql = 'SELECT username, password, salt FROM user WHERE username = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_STR); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + /** @var ChildUser $obj */ + $obj = new ChildUser(); + $obj->hydrate($row); + UserTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildUser|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, ConnectionInterface $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(UserTableMap::COL_USERNAME, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(UserTableMap::COL_USERNAME, $keys, Criteria::IN); + } + + /** + * Filter the query on the username column + * + * Example usage: + * + * $query->filterByUsername('fooValue'); // WHERE username = 'fooValue' + * $query->filterByUsername('%fooValue%'); // WHERE username LIKE '%fooValue%' + * + * + * @param string $username The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function filterByUsername($username = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($username)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $username)) { + $username = str_replace('*', '%', $username); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(UserTableMap::COL_USERNAME, $username, $comparison); + } + + /** + * Filter the query on the password column + * + * Example usage: + * + * $query->filterByPassword('fooValue'); // WHERE password = 'fooValue' + * $query->filterByPassword('%fooValue%'); // WHERE password LIKE '%fooValue%' + * + * + * @param string $password The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function filterByPassword($password = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($password)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $password)) { + $password = str_replace('*', '%', $password); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(UserTableMap::COL_PASSWORD, $password, $comparison); + } + + /** + * Filter the query on the salt column + * + * Example usage: + * + * $query->filterBySalt('fooValue'); // WHERE salt = 'fooValue' + * $query->filterBySalt('%fooValue%'); // WHERE salt LIKE '%fooValue%' + * + * + * @param string $salt The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function filterBySalt($salt = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($salt)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $salt)) { + $salt = str_replace('*', '%', $salt); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(UserTableMap::COL_SALT, $salt, $comparison); + } + + /** + * Exclude object from result + * + * @param ChildUser $user Object to remove from the list of results + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function prune($user = null) + { + if ($user) { + $this->addUsingAlias(UserTableMap::COL_USERNAME, $user->getUsername(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the user table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(UserTableMap::DATABASE_NAME); + } + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con) { + $affectedRows = 0; // initialize var to track total num of affected rows + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + UserTableMap::clearInstancePool(); + UserTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + + /** + * Performs a DELETE on the database based on the current ModelCriteria + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(UserTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(UserTableMap::DATABASE_NAME); + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + return $con->transaction(function () use ($con, $criteria) { + $affectedRows = 0; // initialize var to track total num of affected rows + + UserTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + UserTableMap::clearRelatedInstancePool(); + + return $affectedRows; + }); + } + +} // UserQuery diff --git a/generated-classes/Category.php b/generated-classes/Category.php new file mode 100644 index 0000000..041fe78 --- /dev/null +++ b/generated-classes/Category.php @@ -0,0 +1,18 @@ + array('Id', 'Name', 'Description', ), + self::TYPE_CAMELNAME => array('id', 'name', 'description', ), + self::TYPE_COLNAME => array(CategoryTableMap::COL_ID, CategoryTableMap::COL_NAME, CategoryTableMap::COL_DESCRIPTION, ), + self::TYPE_FIELDNAME => array('id', 'name', 'description', ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'Name' => 1, 'Description' => 2, ), + self::TYPE_CAMELNAME => array('id' => 0, 'name' => 1, 'description' => 2, ), + self::TYPE_COLNAME => array(CategoryTableMap::COL_ID => 0, CategoryTableMap::COL_NAME => 1, CategoryTableMap::COL_DESCRIPTION => 2, ), + self::TYPE_FIELDNAME => array('id' => 0, 'name' => 1, 'description' => 2, ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('category'); + $this->setPhpName('Category'); + $this->setIdentifierQuoting(false); + $this->setClassName('\\Category'); + $this->setPackage(''); + $this->setUseIdGenerator(true); + // columns + $this->addPrimaryKey('id', 'Id', 'INTEGER', true, null, null); + $this->addColumn('name', 'Name', 'VARCHAR', true, 100, null); + $this->addColumn('description', 'Description', 'VARCHAR', false, 1000, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('ProductCategory', '\\ProductCategory', RelationMap::ONE_TO_MANY, array ( + 0 => + array ( + 0 => ':category_id', + 1 => ':id', + ), +), null, null, 'ProductCategories', false); + $this->addRelation('Product', '\\Product', RelationMap::MANY_TO_MANY, array(), null, null, 'Products'); + } // buildRelations() + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return string The primary key hash of the row + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + return (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? CategoryTableMap::CLASS_DEFAULT : CategoryTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (Category object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = CategoryTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = CategoryTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + CategoryTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = CategoryTableMap::OM_CLASS; + /** @var Category $obj */ + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + CategoryTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = CategoryTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = CategoryTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + /** @var Category $obj */ + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + CategoryTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(CategoryTableMap::COL_ID); + $criteria->addSelectColumn(CategoryTableMap::COL_NAME); + $criteria->addSelectColumn(CategoryTableMap::COL_DESCRIPTION); + } else { + $criteria->addSelectColumn($alias . '.id'); + $criteria->addSelectColumn($alias . '.name'); + $criteria->addSelectColumn($alias . '.description'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(CategoryTableMap::DATABASE_NAME)->getTable(CategoryTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(CategoryTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(CategoryTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new CategoryTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a Category or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Category object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(CategoryTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Category) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(CategoryTableMap::DATABASE_NAME); + $criteria->add(CategoryTableMap::COL_ID, (array) $values, Criteria::IN); + } + + $query = CategoryQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { + CategoryTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { + CategoryTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the category table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return CategoryQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a Category or Criteria object. + * + * @param mixed $criteria Criteria or Category object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(CategoryTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from Category object + } + + if ($criteria->containsKey(CategoryTableMap::COL_ID) && $criteria->keyContainsValue(CategoryTableMap::COL_ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.CategoryTableMap::COL_ID.')'); + } + + + // Set the correct dbName + $query = CategoryQuery::create()->mergeWith($criteria); + + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + return $con->transaction(function () use ($con, $query) { + return $query->doInsert($con); + }); + } + +} // CategoryTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +CategoryTableMap::buildTableMap(); diff --git a/generated-classes/Map/ProductCategoryTableMap.php b/generated-classes/Map/ProductCategoryTableMap.php new file mode 100644 index 0000000..262f098 --- /dev/null +++ b/generated-classes/Map/ProductCategoryTableMap.php @@ -0,0 +1,491 @@ + array('ProductId', 'CategoryId', ), + self::TYPE_CAMELNAME => array('productId', 'categoryId', ), + self::TYPE_COLNAME => array(ProductCategoryTableMap::COL_PRODUCT_ID, ProductCategoryTableMap::COL_CATEGORY_ID, ), + self::TYPE_FIELDNAME => array('product_id', 'category_id', ), + self::TYPE_NUM => array(0, 1, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('ProductId' => 0, 'CategoryId' => 1, ), + self::TYPE_CAMELNAME => array('productId' => 0, 'categoryId' => 1, ), + self::TYPE_COLNAME => array(ProductCategoryTableMap::COL_PRODUCT_ID => 0, ProductCategoryTableMap::COL_CATEGORY_ID => 1, ), + self::TYPE_FIELDNAME => array('product_id' => 0, 'category_id' => 1, ), + self::TYPE_NUM => array(0, 1, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('product_category'); + $this->setPhpName('ProductCategory'); + $this->setIdentifierQuoting(false); + $this->setClassName('\\ProductCategory'); + $this->setPackage(''); + $this->setUseIdGenerator(false); + $this->setIsCrossRef(true); + // columns + $this->addForeignPrimaryKey('product_id', 'ProductId', 'INTEGER' , 'product', 'id', true, null, null); + $this->addForeignPrimaryKey('category_id', 'CategoryId', 'INTEGER' , 'category', 'id', true, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('Category', '\\Category', RelationMap::MANY_TO_ONE, array ( + 0 => + array ( + 0 => ':category_id', + 1 => ':id', + ), +), null, null, null, false); + $this->addRelation('Product', '\\Product', RelationMap::MANY_TO_ONE, array ( + 0 => + array ( + 0 => ':product_id', + 1 => ':id', + ), +), null, null, null, false); + } // buildRelations() + + /** + * Adds an object to the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases you may need to explicitly add objects + * to the cache in order to ensure that the same objects are always returned by find*() + * and findPk*() calls. + * + * @param \ProductCategory $obj A \ProductCategory object. + * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). + */ + public static function addInstanceToPool($obj, $key = null) + { + if (Propel::isInstancePoolingEnabled()) { + if (null === $key) { + $key = serialize(array((string) $obj->getProductId(), (string) $obj->getCategoryId())); + } // if key === null + self::$instances[$key] = $obj; + } + } + + /** + * Removes an object from the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases -- especially when you override doDelete + * methods in your stub classes -- you may need to explicitly remove objects + * from the cache in order to prevent returning objects that no longer exist. + * + * @param mixed $value A \ProductCategory object or a primary key value. + */ + public static function removeInstanceFromPool($value) + { + if (Propel::isInstancePoolingEnabled() && null !== $value) { + if (is_object($value) && $value instanceof \ProductCategory) { + $key = serialize(array((string) $value->getProductId(), (string) $value->getCategoryId())); + + } elseif (is_array($value) && count($value) === 2) { + // assume we've been passed a primary key"; + $key = serialize(array((string) $value[0], (string) $value[1])); + } elseif ($value instanceof Criteria) { + self::$instances = []; + + return; + } else { + $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or \ProductCategory object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value, true))); + throw $e; + } + + unset(self::$instances[$key]); + } + } + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return string The primary key hash of the row + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('ProductId', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('CategoryId', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('ProductId', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('CategoryId', TableMap::TYPE_PHPNAME, $indexType)])); + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $pks = []; + + $pks[] = (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('ProductId', TableMap::TYPE_PHPNAME, $indexType) + ]; + $pks[] = (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 1 + $offset + : self::translateFieldName('CategoryId', TableMap::TYPE_PHPNAME, $indexType) + ]; + + return $pks; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? ProductCategoryTableMap::CLASS_DEFAULT : ProductCategoryTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (ProductCategory object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = ProductCategoryTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = ProductCategoryTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + ProductCategoryTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = ProductCategoryTableMap::OM_CLASS; + /** @var ProductCategory $obj */ + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + ProductCategoryTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = ProductCategoryTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = ProductCategoryTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + /** @var ProductCategory $obj */ + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + ProductCategoryTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(ProductCategoryTableMap::COL_PRODUCT_ID); + $criteria->addSelectColumn(ProductCategoryTableMap::COL_CATEGORY_ID); + } else { + $criteria->addSelectColumn($alias . '.product_id'); + $criteria->addSelectColumn($alias . '.category_id'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(ProductCategoryTableMap::DATABASE_NAME)->getTable(ProductCategoryTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(ProductCategoryTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(ProductCategoryTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new ProductCategoryTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a ProductCategory or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ProductCategory object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductCategoryTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \ProductCategory) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(ProductCategoryTableMap::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey values + if (count($values) == count($values, COUNT_RECURSIVE)) { + // array is not multi-dimensional + $values = array($values); + } + foreach ($values as $value) { + $criterion = $criteria->getNewCriterion(ProductCategoryTableMap::COL_PRODUCT_ID, $value[0]); + $criterion->addAnd($criteria->getNewCriterion(ProductCategoryTableMap::COL_CATEGORY_ID, $value[1])); + $criteria->addOr($criterion); + } + } + + $query = ProductCategoryQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { + ProductCategoryTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { + ProductCategoryTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the product_category table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return ProductCategoryQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a ProductCategory or Criteria object. + * + * @param mixed $criteria Criteria or ProductCategory object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductCategoryTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from ProductCategory object + } + + + // Set the correct dbName + $query = ProductCategoryQuery::create()->mergeWith($criteria); + + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + return $con->transaction(function () use ($con, $query) { + return $query->doInsert($con); + }); + } + +} // ProductCategoryTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +ProductCategoryTableMap::buildTableMap(); diff --git a/generated-classes/Map/ProductTableMap.php b/generated-classes/Map/ProductTableMap.php new file mode 100644 index 0000000..820ebc3 --- /dev/null +++ b/generated-classes/Map/ProductTableMap.php @@ -0,0 +1,448 @@ + array('Id', 'Name', 'Price', 'Width', 'Height', 'Description', ), + self::TYPE_CAMELNAME => array('id', 'name', 'price', 'width', 'height', 'description', ), + self::TYPE_COLNAME => array(ProductTableMap::COL_ID, ProductTableMap::COL_NAME, ProductTableMap::COL_PRICE, ProductTableMap::COL_WIDTH, ProductTableMap::COL_HEIGHT, ProductTableMap::COL_DESCRIPTION, ), + self::TYPE_FIELDNAME => array('id', 'name', 'price', 'width', 'height', 'description', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'Name' => 1, 'Price' => 2, 'Width' => 3, 'Height' => 4, 'Description' => 5, ), + self::TYPE_CAMELNAME => array('id' => 0, 'name' => 1, 'price' => 2, 'width' => 3, 'height' => 4, 'description' => 5, ), + self::TYPE_COLNAME => array(ProductTableMap::COL_ID => 0, ProductTableMap::COL_NAME => 1, ProductTableMap::COL_PRICE => 2, ProductTableMap::COL_WIDTH => 3, ProductTableMap::COL_HEIGHT => 4, ProductTableMap::COL_DESCRIPTION => 5, ), + self::TYPE_FIELDNAME => array('id' => 0, 'name' => 1, 'price' => 2, 'width' => 3, 'height' => 4, 'description' => 5, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('product'); + $this->setPhpName('Product'); + $this->setIdentifierQuoting(false); + $this->setClassName('\\Product'); + $this->setPackage(''); + $this->setUseIdGenerator(true); + // columns + $this->addPrimaryKey('id', 'Id', 'INTEGER', true, null, null); + $this->addColumn('name', 'Name', 'VARCHAR', true, 100, null); + $this->addColumn('price', 'Price', 'DECIMAL', true, 10, null); + $this->addColumn('width', 'Width', 'INTEGER', true, null, null); + $this->addColumn('height', 'Height', 'INTEGER', true, null, null); + $this->addColumn('description', 'Description', 'VARCHAR', false, 1000, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('ProductCategory', '\\ProductCategory', RelationMap::ONE_TO_MANY, array ( + 0 => + array ( + 0 => ':product_id', + 1 => ':id', + ), +), null, null, 'ProductCategories', false); + $this->addRelation('Category', '\\Category', RelationMap::MANY_TO_MANY, array(), null, null, 'Categories'); + } // buildRelations() + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return string The primary key hash of the row + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + return (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? ProductTableMap::CLASS_DEFAULT : ProductTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (Product object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = ProductTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = ProductTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + ProductTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = ProductTableMap::OM_CLASS; + /** @var Product $obj */ + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + ProductTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = ProductTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = ProductTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + /** @var Product $obj */ + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + ProductTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(ProductTableMap::COL_ID); + $criteria->addSelectColumn(ProductTableMap::COL_NAME); + $criteria->addSelectColumn(ProductTableMap::COL_PRICE); + $criteria->addSelectColumn(ProductTableMap::COL_WIDTH); + $criteria->addSelectColumn(ProductTableMap::COL_HEIGHT); + $criteria->addSelectColumn(ProductTableMap::COL_DESCRIPTION); + } else { + $criteria->addSelectColumn($alias . '.id'); + $criteria->addSelectColumn($alias . '.name'); + $criteria->addSelectColumn($alias . '.price'); + $criteria->addSelectColumn($alias . '.width'); + $criteria->addSelectColumn($alias . '.height'); + $criteria->addSelectColumn($alias . '.description'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(ProductTableMap::DATABASE_NAME)->getTable(ProductTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(ProductTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(ProductTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new ProductTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a Product or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Product object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Product) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(ProductTableMap::DATABASE_NAME); + $criteria->add(ProductTableMap::COL_ID, (array) $values, Criteria::IN); + } + + $query = ProductQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { + ProductTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { + ProductTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the product table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return ProductQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a Product or Criteria object. + * + * @param mixed $criteria Criteria or Product object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from Product object + } + + if ($criteria->containsKey(ProductTableMap::COL_ID) && $criteria->keyContainsValue(ProductTableMap::COL_ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.ProductTableMap::COL_ID.')'); + } + + + // Set the correct dbName + $query = ProductQuery::create()->mergeWith($criteria); + + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + return $con->transaction(function () use ($con, $query) { + return $query->doInsert($con); + }); + } + +} // ProductTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +ProductTableMap::buildTableMap(); diff --git a/generated-classes/Map/UserTableMap.php b/generated-classes/Map/UserTableMap.php new file mode 100644 index 0000000..8c2e99c --- /dev/null +++ b/generated-classes/Map/UserTableMap.php @@ -0,0 +1,412 @@ + array('Username', 'Password', 'Salt', ), + self::TYPE_CAMELNAME => array('username', 'password', 'salt', ), + self::TYPE_COLNAME => array(UserTableMap::COL_USERNAME, UserTableMap::COL_PASSWORD, UserTableMap::COL_SALT, ), + self::TYPE_FIELDNAME => array('username', 'password', 'salt', ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Username' => 0, 'Password' => 1, 'Salt' => 2, ), + self::TYPE_CAMELNAME => array('username' => 0, 'password' => 1, 'salt' => 2, ), + self::TYPE_COLNAME => array(UserTableMap::COL_USERNAME => 0, UserTableMap::COL_PASSWORD => 1, UserTableMap::COL_SALT => 2, ), + self::TYPE_FIELDNAME => array('username' => 0, 'password' => 1, 'salt' => 2, ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('user'); + $this->setPhpName('User'); + $this->setIdentifierQuoting(false); + $this->setClassName('\\User'); + $this->setPackage(''); + $this->setUseIdGenerator(false); + // columns + $this->addPrimaryKey('username', 'Username', 'VARCHAR', true, 100, null); + $this->addColumn('password', 'Password', 'CHAR', true, 40, null); + $this->addColumn('salt', 'Salt', 'CHAR', true, 20, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + } // buildRelations() + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return string The primary key hash of the row + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Username', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Username', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + return (string) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Username', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? UserTableMap::CLASS_DEFAULT : UserTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (User object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = UserTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = UserTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + UserTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = UserTableMap::OM_CLASS; + /** @var User $obj */ + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + UserTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = UserTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = UserTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + /** @var User $obj */ + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + UserTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(UserTableMap::COL_USERNAME); + $criteria->addSelectColumn(UserTableMap::COL_PASSWORD); + $criteria->addSelectColumn(UserTableMap::COL_SALT); + } else { + $criteria->addSelectColumn($alias . '.username'); + $criteria->addSelectColumn($alias . '.password'); + $criteria->addSelectColumn($alias . '.salt'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(UserTableMap::DATABASE_NAME)->getTable(UserTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(UserTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(UserTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new UserTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a User or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or User object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(UserTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \User) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(UserTableMap::DATABASE_NAME); + $criteria->add(UserTableMap::COL_USERNAME, (array) $values, Criteria::IN); + } + + $query = UserQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { + UserTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { + UserTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the user table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return UserQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a User or Criteria object. + * + * @param mixed $criteria Criteria or User object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(UserTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from User object + } + + + // Set the correct dbName + $query = UserQuery::create()->mergeWith($criteria); + + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + return $con->transaction(function () use ($con, $query) { + return $query->doInsert($con); + }); + } + +} // UserTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +UserTableMap::buildTableMap(); diff --git a/generated-classes/Product.php b/generated-classes/Product.php new file mode 100644 index 0000000..afa6b7d --- /dev/null +++ b/generated-classes/Product.php @@ -0,0 +1,18 @@ +checkVersion('2.0.0-dev'); +$serviceContainer->setAdapterClass('default', 'mysql'); +$manager = new \Propel\Runtime\Connection\ConnectionManagerSingle(); +$manager->setConfiguration(array ( + 'classname' => 'Propel\\Runtime\\Connection\\ConnectionWrapper', + 'dsn' => 'mysql:host=localhost;dbname=catalog', + 'user' => 'root', + 'password' => '', + 'options' => + array ( + 'ATTR_PERSISTENT' => false, + ), + 'attributes' => + array ( + 'ATTR_EMULATE_PREPARES' => false, + ), + 'settings' => + array ( + 'charset' => 'utf8', + 'queries' => + array ( + ), + ), +)); +$manager->setName('default'); +$serviceContainer->setConnectionManager('default', $manager); +$serviceContainer->setDefaultDatasource('default'); \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..205eeb2 --- /dev/null +++ b/index.html @@ -0,0 +1,24 @@ + + + + +Home + + + +

Home

+ +
+

This site will rock your chair. The best products from all over the world. + Furniture the like you have never seen. Contact us a get our catalog or login a order direct from our categories.

+
+
+ + + \ No newline at end of file diff --git a/login.html b/login.html new file mode 100644 index 0000000..4455b0e --- /dev/null +++ b/login.html @@ -0,0 +1,41 @@ + + + + +User + + + +

Customer login

+ +
+
+

User

+
+ +
+
+ +
+
 
+ + +
+
+
+ + + \ No newline at end of file diff --git a/productdetails.php b/productdetails.php new file mode 100644 index 0000000..f5f78f4 --- /dev/null +++ b/productdetails.php @@ -0,0 +1,75 @@ +findOneById($id); +?> + + + + +Productdetails + + + +

getName(); ?>

+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
 
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/products.php b/products.php new file mode 100644 index 0000000..b8391d9 --- /dev/null +++ b/products.php @@ -0,0 +1,45 @@ +filterById($id)->findOne(); +$products = $category->getProducts(); +?> + + + + +Products + + + +

getName(); ?>

+ +
+
+getId()}\">{$product->getName()}"; + echo "
{$product->getDescription()}
"; +} +?> +
+
+
+ + + \ No newline at end of file diff --git a/schema.xml b/schema.xml new file mode 100644 index 0000000..84b458e --- /dev/null +++ b/schema.xml @@ -0,0 +1,46 @@ + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + +
+
diff --git a/styles/style.css b/styles/style.css new file mode 100644 index 0000000..ef2ecf2 --- /dev/null +++ b/styles/style.css @@ -0,0 +1,86 @@ +@CHARSET "UTF-8"; + +u { + text-decoration: underline; +} + +form { + float: left; + width: 450px; + background-color: #ccc; + border: 1px dotted #333; + padding: 5px; + margin: 5px auto; +} + +form h1 { + text-align: center; +} + +div.row { + clear: both; + padding-top: 5px; +} + +div.row label { + float: left; + width: 200px; + text-align: right; +} + +div.row .formw { + float: right; + width: 235px; + text-align: left; +} + +div.spacer { + clear: both; +} + +body { + width: 90%; + margin: 10px auto; + background-color: #fff; + color: #333; + border: 1px solid gray; + line-height: 130%; +} + +header { + padding: .5em; + background-color: #ddd; + border-bottom: 1px solid gray; +} + +header h1 { + padding: 0; + margin: 0; +} + +nav { + float: left; + width: 160px; + margin: 0; + padding: 1em; +} + +#content { + margin-left: 200px; + border-left: 1px solid gray; + padding: 1em; + max-width: 36em; +} + +footer { + clear: both; + margin: 0; + padding: .5em; + color: #333; + background-color: #ddd; + border-top: 1px solid gray; +} + +#content h2 { + margin: 0 0 .5em 0; +} \ No newline at end of file diff --git a/vendor.inc.php b/vendor.inc.php new file mode 100644 index 0000000..fe4eac3 --- /dev/null +++ b/vendor.inc.php @@ -0,0 +1,8 @@ + 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 @@ + + * Jordi Boggiano + * + * 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 + * @author Jordi Boggiano + */ +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 @@ + $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 @@ + 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 @@ + $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 index 0000000..4968909 --- /dev/null +++ b/vendor/propel/propel @@ -0,0 +1 @@ +Subproject commit 4968909779b239360cf52d30036c63452f94859b 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 @@ +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 @@ +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 @@ +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 @@ +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 @@ + " + * + * 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 +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * @author Christophe Coevoet + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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('', $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); + } else { + $this->writeLine('', $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.''; + } + + $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.''; + } + } + } + } + + // render children tags + foreach ($rootChildren as $child) { + $this->writeLine(''); + $this->writeNode($child, $depth + 4); + } + + // render end tag + if (!$rootIsEmptyTag && !$rootIsVariablePrototype) { + $this->writeLine(''); + + $rootEndTag = ''; + $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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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.foo + * twig.extension.bar + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 << + + + + + + + + + + scalar value + + + + + + +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 @@ + + * + * 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 << + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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. + * + * + * + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + +]> + 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 @@ + + 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 @@ + + 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 @@ + + + + + + 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 @@ + + + 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 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 : ''.$xml.''); + + $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix)); + } + + public function getDataForConvertDomToArray() + { + return array( + array(null, ''), + array('bar', 'bar'), + array(array('bar' => 'foobar'), '', true), + array(array('foo' => null), ''), + array(array('foo' => 'bar'), 'bar'), + array(array('foo' => array('foo' => 'bar')), ''), + array(array('foo' => array('foo' => 0)), '0'), + array(array('foo' => array('foo' => 'bar')), 'bar'), + array(array('foo' => array('foo' => 'bar', 'value' => 'text')), 'text'), + array(array('foo' => array('attr' => 'bar', 'foo' => 'text')), 'text'), + array(array('foo' => array('bar', 'text')), 'bartext'), + array(array('foo' => array(array('foo' => 'bar'), array('foo' => 'text'))), ''), + array(array('foo' => array('foo' => array('bar', 'text'))), 'text'), + array(array('foo' => 'bar'), 'bar'), + array(array('foo' => 'text'), 'text'), + array(array('foo' => array('bar' => 'bar', 'value' => 'text')), 'text', false, false), + array(array('attr' => 1, 'b' => 'hello'), 'hello2', 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 @@ + + * + * 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 + * @author Martin Hasoň + */ +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 (bar) + * if the tag also has some nested tags + * + * * The attributes are converted to keys () + * + * * The nested-tags are converted to keys (bar) + * + * @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 @@ + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + 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 @@ + + * + * 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 + * + * @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('%s version %s', $this->getName(), $this->getVersion()); + } + + return 'Console Tool'; + } + + /** + * 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('%s', str_repeat(' ', $len))); + $messages[] = $formatter->format(sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title))))); + foreach ($lines as $line) { + $messages[] = $formatter->format(sprintf(' %s %s', $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('Exception trace:'); + + // 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 %s:%s', $class, $type, $function, $file, $line)); + } + + $output->writeln(''); + $output->writeln(''); + } + } while ($e = $e->getPrevious()); + + if (null !== $this->runningCommand) { + $output->writeln(sprintf('%s', 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 x 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 @@ + + * + * 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 + * + * @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('Install the proctitle PECL to be able to change the process title.'); + } + } + + 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 @@ + + * + * 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 + */ +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(<<%command.name% command displays help for a given command: + + php %command.full_name% list + +You can also output the help in other formats by using the --format option: + + php %command.full_name% --format=xml list + +To display the list of available commands, please use the list 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 @@ + + * + * 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 + */ +class ListCommand extends Command +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('list') + ->setDefinition($this->createDefinition()) + ->setDescription('Lists commands') + ->setHelp(<<%command.name% command lists all commands: + + php %command.full_name% + +You can also display the commands for a specific namespace: + + php %command.full_name% test + +You can also output the information in other formats by using the --format option: + + php %command.full_name% --format=xml + +It's also possible to get raw list of commands (useful for embedding command runner): + + php %command.full_name% --raw +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @internal + */ +class MarkdownDescriptor extends Descriptor +{ + /** + * {@inheritdoc} + */ + protected function describeInputArgument(InputArgument $argument, array $options = array()) + { + $this->write( + '**'.$argument->getName().':**'."\n\n" + .'* Name: '.($argument->getName() ?: '')."\n" + .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n" + .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n" + .'* Description: '.($argument->getDescription() ?: '')."\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())).'`' : '')."\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() ?: '')."\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() ?: '')."\n" + .'* Usage: `'.$command->getSynopsis().'`'."\n" + .'* Aliases: '.(count($command->getAliases()) ? '`'.implode('`, `', $command->getAliases()).'`' : '') + ); + + 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 @@ + + * + * 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 + * + * @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(' (default: %s)', $this->formatDefaultValue($argument->getDefault())); + } else { + $default = ''; + } + + $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($argument->getName()); + + $this->writeText(sprintf(" %-${nameWidth}s %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(' (default: %s)', $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(" %s %-${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() ? ' (multiple values allowed)' : '' + ), $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('Arguments:', $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('Options:', $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('Usage:', $options); + $this->writeText("\n"); + $this->writeText(' '.$command->getSynopsis(), $options); + $this->writeText("\n"); + + if (count($command->getAliases()) > 0) { + $this->writeText("\n"); + $this->writeText('Aliases: '.implode(', ', $command->getAliases()).'', $options); + } + + if ($definition = $command->getNativeDefinition()) { + $this->writeText("\n"); + $this->describeInputDefinition($definition, $options); + } + + $this->writeText("\n"); + + if ($help = $command->getProcessedHelp()) { + $this->writeText('Help:', $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("Usage:\n", $options); + $this->writeText(" command [options] [arguments]\n\n", $options); + $this->writeText('Options:', $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("Available commands for the \"%s\" namespace:", $describedNamespace), $options); + } else { + $this->writeText('Available commands:', $options); + } + + // add commands by namespace + foreach ($description->getNamespaces() as $namespace) { + if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { + $this->writeText("\n"); + $this->writeText(''.$namespace['id'].'', $options); + } + + foreach ($namespace['commands'] as $name) { + $this->writeText("\n"); + $this->writeText(sprintf(" %-${width}s %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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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('/([^\\\\]?) 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 %s %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 %s ", $this->getBorder($id), $errorPrefix); + $this->started[$id]['err'] = true; + } + + $message .= str_replace("\n", sprintf("\n%s %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 %s ", $this->getBorder($id), $prefix); + $this->started[$id]['out'] = true; + } + + $message .= str_replace("\n", sprintf("\n%s %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 %s %s\n", $trailingEOL, $this->getBorder($id), $prefix, $message); + } + + $message = sprintf("%s%s %s %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(' ', $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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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(" [%-${width}s] %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(''.substr($matches[$ofs], $i).''); + // 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 @@ + + * + * 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 + */ +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', $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', $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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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('%s', $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 @@ + + * + * 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 + * @author Chris Jones + */ +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 @@ + + * + * 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 + * @author Fabien Potencier + * + * @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 @@ + + * + * 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 + */ +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(" [%-${width}s] %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(''.substr($matches[$ofs], $i).''); + // 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->getMessage().''; + } + + $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 @@ + + * + * 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 + * @author Саша Стаменковић + */ +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 @@ + + * + * 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 Саша Стаменковић + * @author Fabien Potencier + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * @author Саша Стаменковић + */ +class TableStyle +{ + private $paddingChar = ' '; + private $horizontalBorderChar = '-'; + private $verticalBorderChar = '|'; + private $crossingChar = '+'; + private $cellHeaderFormat = '%s'; + 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @api + */ +class StringInput extends ArgvInput +{ + const REGEX_STRING = '([^\s]+?)(?:\s|(?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 @@ + + * + * 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 + * @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', $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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * @author Tobias Schultze + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 %s', $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 Binary files /dev/null and b/vendor/symfony/console/Symfony/Component/Console/Resources/bin/hiddeninput.exe 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 @@ + + * + * 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 + * @author Martin Hasoň + */ +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(<<Running with process isolation, you should consider this: + * 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('The command terminated with an error status (%s)', $ret)); + } + } + } + + /** + * Returns the shell header. + * + * @return string The header string + */ + protected function getHeader() + { + return <<{$this->application->getName()} shell ({$this->application->getVersion()}). + +At the prompt, type help for some help, +or list to get a list of available commands. + +To exit the shell, type ^D. + +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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('foo version bar', $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 @@ + + * + * 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 @@ + + * + * 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('/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('/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 @@ + + * + * 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('//', $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 = <<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 = <<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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ +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 @@ +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 @@ +setName('foo3:bar') + ->setDescription('The foo3:bar command') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + try { + throw new \Exception('First exception

this is html

'); + } catch (\Exception $e) { + throw new \Exception('Second exception comment', 0, $e); + } + } catch (\Exception $e) { + throw new \Exception('Third exception 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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the 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 list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n 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 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: + +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. + +### Arguments: + +**command_name:** + +* Name: command_name +* Is required: no +* Is array: no +* Description: The command name +* Default: `'help'` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output help as XML +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: To output help in other formats +* Default: `'txt'` + +**raw:** + +* Name: `--raw` +* Shortcut: +* 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: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* 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: + +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 + +### Arguments: + +**namespace:** + +* Name: namespace +* Is required: no +* Is array: no +* Description: The namespace name +* Default: `NULL` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output list as XML +* Default: `false` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command list +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* 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 @@ +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_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 @@ + + + + + help [--xml] [--format="..."] [--raw] [command_name] + Displays help for a command + 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. + + + + The command name + + help + + + + + + + + + + + + + + + + + + list [--xml] [--raw] [--format="..."] [namespace] + Lists commands + 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> + + + + The namespace name + + + + + + + + + + + + + help + list + + + 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 help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the 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 list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n 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 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: + +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. + +### Arguments: + +**command_name:** + +* Name: command_name +* Is required: no +* Is array: no +* Description: The command name +* Default: `'help'` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output help as XML +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: To output help in other formats +* Default: `'txt'` + +**raw:** + +* Name: `--raw` +* Shortcut: +* 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: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* 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: + +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 + +### Arguments: + +**namespace:** + +* Name: namespace +* Is required: no +* Is array: no +* Description: The namespace name +* Default: `NULL` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output list as XML +* Default: `false` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command list +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* 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: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* 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: + +command 2 help + +### Arguments: + +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` + +### Options: + +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* 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: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* 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 @@ +My Symfony application version v1.0 + +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: + alias1 command 1 description + alias2 command 1 description + help Displays help for a command + list Lists commands +descriptor + descriptor:command1 command 1 description + descriptor:command2 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 @@ + + + + + help [--xml] [--format="..."] [--raw] [command_name] + Displays help for a command + 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. + + + + The command name + + help + + + + + + + + + + + + + + + + + + list [--xml] [--raw] [--format="..."] [namespace] + Lists commands + 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> + + + + The namespace name + + + + + + + + + + + descriptor:command1 + command 1 description + command 1 help + + alias1 + alias2 + + + + + + + + + + + + + + descriptor:command2 [-o|--option_name] argument_name + command 2 description + command 2 help + + + + + + + + + + + + + + + + + + + + + + alias1 + alias2 + help + list + + + descriptor:command1 + descriptor:command2 + + + 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 @@ +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: + afoobar The foo:bar command + help Displays help for a command + list Lists commands +foo + foo:bar 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 @@ +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 for the "foo" namespace: + foo:bar 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 @@ + + + + + help [--xml] [--format="..."] [--raw] [command_name] + Displays help for a command + 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. + + + + The command name + + help + + + + + + + + + + + + + + + + + + list [--xml] [--raw] [--format="..."] [namespace] + Lists commands + 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> + + + + The namespace name + + + + + + + + + + + foo:bar + The foo:bar command + + + afoobar + + + + + + + + + + + + + + + + afoobar + help + list + + + foo:bar + + + 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 @@ + + + + + foo:bar + The foo:bar command + + + afoobar + + + + + + + + + + + + + + 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 @@ +Console Tool \ 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

this is html

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

this is html

  +  + + +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 @@ +Usage: + descriptor:command1 + +Aliases: alias1, alias2 + +Help: + 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 @@ + + + descriptor:command1 + command 1 description + command 1 help + + alias1 + alias2 + + + + 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: + +command 2 help + +### Arguments: + +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` + +### Options: + +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* 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 @@ +Usage: + descriptor:command2 [-o|--option_name] argument_name + +Arguments: + argument_name + +Options: + --option_name (-o) + +Help: + 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 @@ + + + descriptor:command2 [-o|--option_name] argument_name + command 2 description + command 2 help + + + + + + + + + + + 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 @@ +Usage: + namespace:name + +Aliases: name +Arguments: + command The command to execute + +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 + +Help: + 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 @@ + + + namespace:name + description + help + + name + + + + The command to execute + + + + + + + + + + + + + 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 @@ +Arguments: + foo The foo argument + baz The baz argument (default: true) + bar The bar argument (default: ["http://foo.com/"]) + +Options: + --foo (-f) The foo option + --baz The baz option (default: false) + --bar (-b) The bar option (default: "bar") + --qux The qux option (default: ["http://foo.com/","bar"]) (multiple values allowed) + --qux2 The qux2 option (default: {"foo":"bar"}) (multiple values allowed) 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 @@ + + + + + The foo argument + + + + The baz argument + + true + + + + The bar argument + + bar + + + + + + + + + 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: +* 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 @@ + argument_name 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 @@ + + + + + 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 @@ + argument_name 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 @@ + + + argument description + + 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 @@ + argument_name argument description (default: "default_value") 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 @@ + + + argument description + + default_value + + 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 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 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 @@ + + + + + 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: +* 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 @@ +Arguments: + argument_name 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 @@ + + + + + + + + + + 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: +* 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 @@ +Options: + --option_name (-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 @@ + + + + + + + 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: +* Default: `NULL` + +### Options: + +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* 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 @@ +Arguments: + argument_name + +Options: + --option_name (-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 @@ + + + + + + + + + + + + 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: +* 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 @@ + --option_name (-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 @@ + + 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 @@ + --option_name (-o) option description (default: "default_value") 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 @@ + + 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 @@ + --option_name (-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 @@ + + 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 @@ + --option_name (-o) option description (multiple values allowed) 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 @@ + + 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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('fooformat('foo\\assertEquals('some info', $formatter->format('\\some info\\')); + $this->assertEquals("\\some info\\", OutputFormatter::escape('some info')); + + $this->assertEquals( + "\033[33mSymfony\\Component\\Console does work very well!\033[39m", + $formatter->format('Symfony\Component\Console does work very well!') + ); + } + + 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('some error') + ); + $this->assertEquals( + "\033[32msome info\033[39m", + $formatter->format('some info') + ); + $this->assertEquals( + "\033[33msome comment\033[39m", + $formatter->format('some comment') + ); + $this->assertEquals( + "\033[30;46msome question\033[39;49m", + $formatter->format('some 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('some some info error') + ); + } + + public function testAdjacentStyles() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "\033[37;41msome error\033[39;49m\033[32msome info\033[39m", + $formatter->format('some errorsome info') + ); + } + + public function testStyleMatchingNotGreedy() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "(\033[32m>=2.0,<2.3\033[39m)", + $formatter->format('(>=2.0,<2.3)') + ); + } + + public function testStyleEscaping() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "(\033[32mz>=2.0,format('('.$formatter->escape('z>=2.0,)') + ); + + $this->assertEquals( + "\033[32msome error\033[39m", + $formatter->format(''.$formatter->escape('some error').'') + ); + } + + 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('errorinfocommenterror') + ); + } + + 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('some custom msg')); + } + + 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('some custom msg')); + } + + public function testInlineStyle() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('some text')); + $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('some text')); + } + + public function testNonStyleTag() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals("\033[32msome \033[39m\033[32m\033[39m\033[32m \033[39m\033[32m\033[39m\033[32m styled \033[39m\033[32m

\033[39m\033[32msingle-char tag\033[39m\033[32m

\033[39m", $formatter->format('some styled

single-char tag

')); + } + + public function testFormatLongString() + { + $formatter = new OutputFormatter(true); + $long = str_repeat("\\", 14000); + $this->assertEquals("\033[37;41msome error\033[39;49m".$long, $formatter->format('some 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('some error') + ); + $this->assertEquals( + 'some info', $formatter->format('some info') + ); + $this->assertEquals( + 'some comment', $formatter->format('some comment') + ); + $this->assertEquals( + 'some question', $formatter->format('some question') + ); + + $formatter->setDecorated(true); + + $this->assertEquals( + "\033[37;41msome error\033[39;49m", $formatter->format('some error') + ); + $this->assertEquals( + "\033[32msome info\033[39m", $formatter->format('some info') + ); + $this->assertEquals( + "\033[33msome comment\033[39m", $formatter->format('some comment') + ); + $this->assertEquals( + "\033[30;46msome question\033[39;49m", $formatter->format('some question') + ); + } + + public function testContentWithLineBreaks() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals(<<format(<< +some text
+EOF + )); + + $this->assertEquals(<<format(<<some text +
+EOF + )); + + $this->assertEquals(<<format(<< +some text +
+EOF + )); + + $this->assertEquals(<<format(<< +some text +more text +
+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 @@ + + * + * 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( + '[cli] 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( + ' Some text to display ', + $formatter->formatBlock('Some text to display', 'error'), + '::formatBlock() formats a message in a block' + ); + + $this->assertEquals( + ' Some text to display '."\n". + ' foo bar ', + $formatter->formatBlock(array('Some text to display', 'foo bar'), 'error'), + '::formatBlock() formats a message in a block' + ); + + $this->assertEquals( + ' '."\n". + ' Some text to display '."\n". + ' ', + $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( + ' '."\n". + ' Du texte à afficher '."\n". + ' ', + $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( + ' '."\n". + ' 表示するテキスト '."\n". + ' ', + $formatter->formatBlock('表示するテキスト', 'error', true), + '::formatBlock() formats a message in a block' + ); + } + + public function testFormatBlockLGEscaping() + { + $formatter = new FormatterHelper(); + + $this->assertEquals( + ' '."\n". + ' \some info\ '."\n". + ' ', + $formatter->formatBlock('some 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 @@ + + * + * 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 @@ + + * + * 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 + // AcsTest + // + // + // Test + // + // S + // F00oo + $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 @@ + + * + * 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 @@ + + * + * 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, +<< array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + TableHelper::LAYOUT_DEFAULT, +<<
array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-700', 'Divine Com', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + TableHelper::LAYOUT_DEFAULT, +<<
99921-58-10-700 | Divine Com | 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 = +<<
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 = + <<
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 @@ + + * + * 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 = <<42\";" + OUT 42 + RES Command ran successfully + +EOT; + $successOutputProcessDebug = <<42\";"', 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 @@ + + * + * 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 @@ + + * + * 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 + // AcsTest + // + // + // Test + // + // S + // F00oo + $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 @@ + + * + * 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', +<<
array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + 'default', +<<
array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-700', 'Divine Com', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + 'default', +<<
99921-58-10-700 | Divine Com | 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 = +<<
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 = +<<
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 = +<<
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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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('foo', Output::OUTPUT_RAW, "foo\n"), + array('foo', Output::OUTPUT_PLAIN, "foo\n"), + ); + } + + public function testWriteWithDecorationTurnedOff() + { + $output = new TestOutput(); + $output->setDecorated(false); + $output->writeln('foo'); + $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'); + $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', 24); + } + + public function testWriteWithInvalidStyle() + { + $output = new TestOutput(); + + $output->clear(); + $output->write('foo'); + $this->assertEquals('foo', $output->output, '->write() do nothing when a style does not exist'); + + $output->clear(); + $output->writeln('foo'); + $this->assertEquals("foo\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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * @author Christian Gärtner + */ +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 @@ + + * + * 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 + * @author Christian Gärtner + * @author Fabien Potencier + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * @author Romain Neutron + * @author Nicolas Grekas + */ +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 +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ +'); + + $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 @@ + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + + + + 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 PHP port + * @author Richard Clamp Perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 PHP port + * @author Richard Clamp Perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * @author Włodzimierz Gajda + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * @author Włodzimierz Gajda + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 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 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 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 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 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 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 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 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 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 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 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + +* +* 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + + 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +class PhpFileDumper extends FileDumper +{ + /** + * {@inheritdoc} + */ + protected function format(MessageCatalogue $messages, $domain) + { + $output = "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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 <<[\[\]]) + \s* + (?P-Inf|\-?\d+(\.\d+)?) + \s*,\s* + (?P\+?Inf|\-?\d+(\.\d+)?) + \s* + (?P[\[\]]) +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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ć + * + * @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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + + + + + + + + + + + + + + Values for the attribute 'context-type'. + + + + + Indicates a database content. + + + + + Indicates the content of an element within an XML document. + + + + + Indicates the name of an element within an XML document. + + + + + Indicates the line number from the sourcefile (see context-type="sourcefile") where the <source> is found. + + + + + Indicates a the number of parameters contained within the <source>. + + + + + Indicates notes pertaining to the parameters in the <source>. + + + + + Indicates the content of a record within a database. + + + + + Indicates the name of a record within a database. + + + + + 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 <file> attribute in that this sourcefile is one of many that make up that file. + + + + + + + Values for the attribute 'count-type'. + + + + + 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. + + + + + Indicates the count units are translation units existing already in the same document. + + + + + Indicates a total count. + + + + + + + Values for the attribute 'ctype' when used other elements than <ph> or <x>. + + + + + Indicates a run of bolded text. + + + + + Indicates a run of text in italics. + + + + + Indicates a run of underlined text. + + + + + Indicates a run of hyper-text. + + + + + + + Values for the attribute 'ctype' when used with <ph> or <x>. + + + + + Indicates a inline image. + + + + + Indicates a page break. + + + + + Indicates a line break. + + + + + + + + + + + + Values for the attribute 'datatype'. + + + + + Indicates Active Server Page data. + + + + + Indicates C source file data. + + + + + Indicates Channel Definition Format (CDF) data. + + + + + Indicates ColdFusion data. + + + + + Indicates C++ source file data. + + + + + Indicates C-Sharp data. + + + + + Indicates strings from C, ASM, and driver files data. + + + + + Indicates comma-separated values data. + + + + + Indicates database data. + + + + + Indicates portions of document that follows data and contains metadata. + + + + + Indicates portions of document that precedes data and contains metadata. + + + + + Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import). + + + + + Indicates standard user input screen data. + + + + + Indicates HyperText Markup Language (HTML) data - document instance. + + + + + Indicates content within an HTML document’s <body> element. + + + + + Indicates Windows INI file data. + + + + + Indicates Interleaf data. + + + + + Indicates Java source file data (extension '.java'). + + + + + Indicates Java property resource bundle data. + + + + + Indicates Java list resource bundle data. + + + + + Indicates JavaScript source file data. + + + + + Indicates JScript source file data. + + + + + Indicates information relating to formatting. + + + + + Indicates LISP source file data. + + + + + Indicates information relating to margin formats. + + + + + Indicates a file containing menu. + + + + + Indicates numerically identified string table. + + + + + Indicates Maker Interchange Format (MIF) data. + + + + + Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute. + + + + + Indicates GNU Machine Object data. + + + + + Indicates Message Librarian strings created by Novell's Message Librarian Tool. + + + + + Indicates information to be displayed at the bottom of each page of a document. + + + + + Indicates information to be displayed at the top of each page of a document. + + + + + Indicates a list of property values (e.g., settings within INI files or preferences dialog). + + + + + Indicates Pascal source file data. + + + + + Indicates Hypertext Preprocessor data. + + + + + Indicates plain text file (no formatting other than, possibly, wrapping). + + + + + Indicates GNU Portable Object file. + + + + + Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc. + + + + + Indicates Windows .NET binary resources. + + + + + Indicates Windows .NET Resources. + + + + + Indicates Rich Text Format (RTF) data. + + + + + Indicates Standard Generalized Markup Language (SGML) data - document instance. + + + + + Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD). + + + + + Indicates Scalable Vector Graphic (SVG) data. + + + + + Indicates VisualBasic Script source file. + + + + + Indicates warning message. + + + + + Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file). + + + + + Indicates Extensible HyperText Markup Language (XHTML) data - document instance. + + + + + Indicates Extensible Markup Language (XML) data - document instance. + + + + + Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD). + + + + + Indicates Extensible Stylesheet Language (XSL) data. + + + + + Indicates XUL elements. + + + + + + + Values for the attribute 'mtype'. + + + + + Indicates the marked text is an abbreviation. + + + + + ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept. + + + + + 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'). + + + + + 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'). + + + + + ISO-12620: A proper-name term, such as the name of an agency or other proper entity. + + + + + 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. + + + + + ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language. + + + + + Indicates the marked text is a date and/or time. + + + + + 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. + + + + + ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form. + + + + + ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula. + + + + + ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record. + + + + + 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'). + + + + + ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body. + + + + + ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages. + + + + + 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. + + + + + ISO-12620 2.1.17: A unit to track object. + + + + + Indicates the marked text is a name. + + + + + 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. + + + + + ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system. + + + + + Indicates the marked text is a phrase. + + + + + 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. + + + + + Indicates the marked text should not be translated. + + + + + 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. + + + + + Indicates that the marked text represents a segment. + + + + + ISO-12620 2.1.18.2: A fixed, lexicalized phrase. + + + + + 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'). + + + + + 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. + + + + + ISO-12620 2.1.19: A fixed chunk of recurring text. + + + + + ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof. + + + + + 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. + + + + + ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language. + + + + + Indicates the marked text is a term. + + + + + 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. + + + + + 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. + + + + + 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'). + + + + + ISO-12620 2.1.9: One of the alternate forms of a term. + + + + + + + Values for the attribute 'restype'. + + + + + Indicates a Windows RC AUTO3STATE control. + + + + + Indicates a Windows RC AUTOCHECKBOX control. + + + + + Indicates a Windows RC AUTORADIOBUTTON control. + + + + + Indicates a Windows RC BEDIT control. + + + + + Indicates a bitmap, for example a BITMAP resource in Windows. + + + + + Indicates a button object, for example a BUTTON control Windows. + + + + + Indicates a caption, such as the caption of a dialog box. + + + + + Indicates the cell in a table, for example the content of the <td> element in HTML. + + + + + Indicates check box object, for example a CHECKBOX control in Windows. + + + + + Indicates a menu item with an associated checkbox. + + + + + Indicates a list box, but with a check-box for each item. + + + + + Indicates a color selection dialog. + + + + + Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows. + + + + + Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234). + + + + + Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403). + + + + + Indicates a UI base class element that cannot be represented by any other element. + + + + + Indicates a context menu. + + + + + Indicates a Windows RC CTEXT control. + + + + + Indicates a cursor, for example a CURSOR resource in Windows. + + + + + Indicates a date/time picker. + + + + + Indicates a Windows RC DEFPUSHBUTTON control. + + + + + Indicates a dialog box. + + + + + Indicates a Windows RC DLGINIT resource block. + + + + + Indicates an edit box object, for example an EDIT control in Windows. + + + + + Indicates a filename. + + + + + Indicates a file dialog. + + + + + Indicates a footnote. + + + + + Indicates a font name. + + + + + Indicates a footer. + + + + + Indicates a frame object. + + + + + Indicates a XUL grid element. + + + + + Indicates a groupbox object, for example a GROUPBOX control in Windows. + + + + + Indicates a header item. + + + + + Indicates a heading, such has the content of <h1>, <h2>, etc. in HTML. + + + + + Indicates a Windows RC HEDIT control. + + + + + Indicates a horizontal scrollbar. + + + + + Indicates an icon, for example an ICON resource in Windows. + + + + + Indicates a Windows RC IEDIT control. + + + + + Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF. + + + + + Indicates a label object. + + + + + Indicates a label that is also a HTML link (not necessarily a URL). + + + + + Indicates a list (a group of list-items, for example an <ol> or <ul> element in HTML). + + + + + Indicates a listbox object, for example an LISTBOX control in Windows. + + + + + Indicates an list item (an entry in a list). + + + + + Indicates a Windows RC LTEXT control. + + + + + Indicates a menu (a group of menu-items). + + + + + Indicates a toolbar containing one or more tope level menus. + + + + + Indicates a menu item (an entry in a menu). + + + + + Indicates a XUL menuseparator element. + + + + + Indicates a message, for example an entry in a MESSAGETABLE resource in Windows. + + + + + Indicates a calendar control. + + + + + Indicates an edit box beside a spin control. + + + + + Indicates a catch all for rectangular areas. + + + + + Indicates a standalone menu not necessarily associated with a menubar. + + + + + Indicates a pushbox object, for example a PUSHBOX control in Windows. + + + + + Indicates a Windows RC PUSHBUTTON control. + + + + + Indicates a radio button object. + + + + + Indicates a menuitem with associated radio button. + + + + + Indicates raw data resources for an application. + + + + + Indicates a row in a table. + + + + + Indicates a Windows RC RTEXT control. + + + + + Indicates a user navigable container used to show a portion of a document. + + + + + Indicates a generic divider object (e.g. menu group separator). + + + + + Windows accelerators, shortcuts in resource or property files. + + + + + Indicates a UI control to indicate process activity but not progress. + + + + + Indicates a splitter bar. + + + + + Indicates a Windows RC STATE3 control. + + + + + Indicates a window for providing feedback to the users, like 'read-only', etc. + + + + + Indicates a string, for example an entry in a STRINGTABLE resource in Windows. + + + + + Indicates a layers of controls with a tab to select layers. + + + + + Indicates a display and edits regular two-dimensional tables of cells. + + + + + Indicates a XUL textbox element. + + + + + Indicates a UI button that can be toggled to on or off state. + + + + + Indicates an array of controls, usually buttons. + + + + + Indicates a pop up tool tip text. + + + + + Indicates a bar with a pointer indicating a position within a certain range. + + + + + Indicates a control that displays a set of hierarchical data. + + + + + Indicates a URI (URN or URL). + + + + + Indicates a Windows RC USERBUTTON control. + + + + + Indicates a user-defined control like CONTROL control in Windows. + + + + + Indicates the text of a variable. + + + + + Indicates version information about a resource like VERSIONINFO in Windows. + + + + + Indicates a vertical scrollbar. + + + + + Indicates a graphical window. + + + + + + + Values for the attribute 'size-unit'. + + + + + Indicates a size in 8-bit bytes. + + + + + Indicates a size in Unicode characters. + + + + + Indicates a size in columns. Used for HTML text area. + + + + + Indicates a size in centimeters. + + + + + Indicates a size in dialog units, as defined in Windows resources. + + + + + Indicates a size in 'font-size' units (as defined in CSS). + + + + + Indicates a size in 'x-height' units (as defined in CSS). + + + + + 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' + + + + + Indicates a size in inches. + + + + + Indicates a size in millimeters. + + + + + Indicates a size in percentage. + + + + + Indicates a size in pixels. + + + + + Indicates a size in point. + + + + + Indicates a size in rows. Used for HTML text area. + + + + + + + Values for the attribute 'state'. + + + + + Indicates the terminating state. + + + + + Indicates only non-textual information needs adaptation. + + + + + Indicates both text and non-textual information needs adaptation. + + + + + Indicates only non-textual information needs review. + + + + + Indicates both text and non-textual information needs review. + + + + + Indicates that only the text of the item needs to be reviewed. + + + + + Indicates that the item needs to be translated. + + + + + Indicates that the item is new. For example, translation units that were not in a previous version of the document. + + + + + Indicates that changes are reviewed and approved. + + + + + Indicates that the item has been translated. + + + + + + + Values for the attribute 'state-qualifier'. + + + + + 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. + + + + + 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.). + + + + + Indicates a match based on matching IDs (in addition to matching text). + + + + + Indicates a translation derived from a glossary. + + + + + Indicates a translation derived from existing translation. + + + + + Indicates a translation derived from machine translation. + + + + + Indicates a translation derived from a translation repository. + + + + + Indicates a translation derived from a translation memory. + + + + + Indicates the translation is suggested by machine translation. + + + + + Indicates that the item has been rejected because of incorrect grammar. + + + + + Indicates that the item has been rejected because it is incorrect. + + + + + Indicates that the item has been rejected because it is too long or too short. + + + + + Indicates that the item has been rejected because of incorrect spelling. + + + + + Indicates the translation is suggested by translation memory. + + + + + + + Values for the attribute 'unit'. + + + + + Refers to words. + + + + + Refers to pages. + + + + + Refers to <trans-unit> elements. + + + + + Refers to <bin-unit> elements. + + + + + Refers to glyphs. + + + + + Refers to <trans-unit> and/or <bin-unit> elements. + + + + + Refers to the occurrences of instances defined by the count-type value. + + + + + Refers to characters. + + + + + Refers to lines. + + + + + Refers to sentences. + + + + + Refers to paragraphs. + + + + + Refers to segments. + + + + + Refers to placeables (inline elements). + + + + + + + Values for the attribute 'priority'. + + + + + Highest priority. + + + + + High priority. + + + + + High priority, but not as important as 2. + + + + + High priority, but not as important as 3. + + + + + Medium priority, but more important than 6. + + + + + Medium priority, but less important than 5. + + + + + Low priority, but more important than 8. + + + + + Low priority, but more important than 9. + + + + + Low priority. + + + + + Lowest priority. + + + + + + + + + This value indicates that all properties can be reformatted. This value must be used alone. + + + + + This value indicates that no properties should be reformatted. This value must be used alone. + + + + + + + + + + + + + This value indicates that all information in the coord attribute can be modified. + + + + + This value indicates that the x information in the coord attribute can be modified. + + + + + This value indicates that the y information in the coord attribute can be modified. + + + + + This value indicates that the cx information in the coord attribute can be modified. + + + + + This value indicates that the cy information in the coord attribute can be modified. + + + + + This value indicates that all the information in the font attribute can be modified. + + + + + This value indicates that the name information in the font attribute can be modified. + + + + + This value indicates that the size information in the font attribute can be modified. + + + + + This value indicates that the weight information in the font attribute can be modified. + + + + + This value indicates that the information in the css-style attribute can be modified. + + + + + This value indicates that the information in the style attribute can be modified. + + + + + This value indicates that the information in the exstyle attribute can be modified. + + + + + + + + + + + + + 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. + + + + + Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed. + + + + + Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed. + + + + + + + + + Represents a translation proposal from a translation memory or other resource. + + + + + Represents a previous version of the target element. + + + + + Represents a rejected version of the target element. + + + + + Represents a translation to be used for reference purposes only, for example from a related product or a different language. + + + + + Represents a proposed translation that was used for the translation of the trans-unit, possibly modified. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Values for the attribute 'coord'. + + + + + + + + Version values: 1.0 and 1.1 are allowed for backward compatibility. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + +
+

About the XML namespace

+ +
+

+ + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. +

+

+ See + http://www.w3.org/XML/1998/namespace.html and + + http://www.w3.org/TR/REC-xml for information + about this namespace. +

+ +

+ 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. +

+

+ See further below in this document for more information about how to refer to this schema document from your own + XSD schema documents and about the + namespace-versioning policy governing this schema document. +

+
+
+ +
+
+ + + + +
+ +

lang (as an attribute name)

+

+ + 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.

+ +
+
+

Notes

+

+ 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. +

+

+ + See BCP 47 at + http://www.rfc-editor.org/rfc/bcp/bcp47.txt + and the IANA language subtag registry at + + http://www.iana.org/assignments/language-subtag-registry + for further information. +

+

+ + The union allows for the 'un-declaration' of xml:lang with + the empty string. +

+
+
+
+ + + + + + + + + + +
+ + + + + +
+ +

space (as an attribute name)

+

+ 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.

+ +
+
+
+ + + + + + + +
+ + + + +
+ +

base (as an attribute name)

+

+ 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.

+ +

+ See http://www.w3.org/TR/xmlbase/ + for information about this attribute. +

+ +
+
+
+
+ + + + +
+ +

id (as an attribute name)

+

+ + 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.

+ +

+ See http://www.w3.org/TR/xml-id/ + for information about this attribute. +

+
+
+
+ +
+ + + + + + + + + + + +
+ +

Father (in any context at all)

+ +
+

+ 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: +

+
+

+ + 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". +

+
+
+
+
+
+ + + + +
+

About this schema document

+ +
+

+ This schema defines attributes and an attribute group suitable + for use by schemas wishing to allow xml:base, + xml:lang, xml:space or + xml:id attributes on elements they define. +

+ +

+ To enable this, such a schema must import this schema for + the XML namespace, e.g. as follows: +

+
+          <schema.. .>
+          .. .
+           <import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+     
+

+ or +

+
+
+           <import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+     
+

+ Subsequently, qualified reference to any of the attributes or the + group defined below will have the desired effect, e.g. +

+
+          <type.. .>
+          .. .
+           <attributeGroup ref="xml:specialAttrs"/>
+     
+

+ will define a type which will schema-validate an instance element + with any of those attributes. +

+ +
+
+
+
+ + + +
+

Versioning policy for this schema document

+ +
+

+ In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + + http://www.w3.org/2009/01/xml.xsd. +

+

+ At the date of issue it can also be found at + + http://www.w3.org/2001/xml.xsd. +

+ +

+ 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 + http://www.w3.org/2001/xml.xsd + + will change accordingly; the version at + + http://www.w3.org/2009/01/xml.xsd + + will not change. +

+

+ + Previous dated (and unchanging) versions of this schema + document are at: +

+ +
+
+
+
+ +
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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * @author Bernhard Schussek + * + * @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::getIntervalRegexp().')\s*(?P.*?)$/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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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' => ' & ', + )); + $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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 Binary files /dev/null and b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.mo 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 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 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 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 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 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 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 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 @@ + + + + + + foo + br + bz + + + bar + f + + + + 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 @@ + + + + + + foo + bar + + + extra + + + key + + + + test + with + note + + + + 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 @@ + + + + + + foo + bar + + + + 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 Binary files /dev/null and b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.mo 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 @@ + + + + + + + bar + + + bar source + baz + + + baz + foo + + + + 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 Binary files /dev/null and b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res 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 Binary files /dev/null and b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res 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 Binary files /dev/null and b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat 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 Binary files /dev/null and b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res 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 @@ + + + + + + foo + bar + baz + + + key + + baz + qux + + + key.with.cdata + & ]]> + + + + 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 Binary files /dev/null and b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.mo 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 @@ + '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 @@ + + + + resources + + foo + bar + + + 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 @@ + + + + + + foo + bar + + + extra + + + key + + + + test + with + note + + + + 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 @@ + + + + + + + foo + bar + + + + 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 @@ + + + + + + foo + bar + foo + + + extra + bar + + + key + + baz + qux + + + + 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 @@ + + * + * 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 + * + * @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(<<addFallbackCatalogue(\$catalogue%s); + + +EOF + , + $fallbackSuffix, + $fallback, + var_export($this->catalogues[$fallback]->all(), true), + $currentSuffix, + $fallbackSuffix + ); + $current = $fallback; + } + + $content = sprintf(<<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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./vendor + ./Tests + + + + 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Constraints\ExpressionValidator; + +/** + * Default implementation of the ConstraintValidatorFactoryInterface. + * + * This enforces the convention that the validatedBy() method on any + * Constraint will return the class name of the ConstraintValidator that + * should validate the Constraint. + * + * @author Bernhard Schussek + */ +class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface +{ + protected $validators = 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 @@ + + * + * 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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +/** + * Default implementation of {@ConstraintViolationInterface}. + * + * @author Bernhard Schussek + */ +class ConstraintViolation implements ConstraintViolationInterface +{ + /** + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +/** + * A violation of a constraint that happened during validation. + * + * For each constraint that fails during validation one or more violations are + * created. The violations store the violation message, the path to the failing + * element in the validation graph and the root element that was originally + * passed to the validator. For example, take the following graph: + * + *
+ * (Person)---(firstName: string)
+ *      \
+ *   (address: Address)---(street: string)
+ * 
+ * + * If the Person object is validated and validation fails for the + * "firstName" property, the generated violation has the Person + * instance as root and the property path "firstName". If validation fails + * for the "street" property of the related Address instance, the root + * element is still the person, but the property path is "address.street". + * + * @author Bernhard Schussek + * + * @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": + * + *
    + *
  • Please select exactly one entry. (choices=1)
  • + *
  • Please select two entries. (choices=2)
  • + *
+ * + * This method returns the value of the parameter for choosing the right + * pluralization form (in this case "choices"). + * + * @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 Person instance with a property + * "address" that contains an Address instance + * with an invalid property "street", the generated property + * path is "address.street". Property access is denoted by + * dots, while array access is denoted by square brackets, + * for example "addresses[1].street". + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Metadata for the CardSchemeValidator. + * + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Tim Nagel + * @author Bernhard Schussek + */ +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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * Validates that a card number belongs to a specified scheme. + * + * @author Tim Nagel + * @author Bernhard Schussek + * + * @see 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * @author Florian Eckerstorfer + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @author Bernhard Schussek + */ +abstract class Existence extends Composite +{ + public $constraints = 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 @@ + + * + * 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 + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Manuel Reinhard + * @author Michael Schummel + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * @author Michael Schummel + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Benjamin Dulau + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * @author Joseph Bielawski + * + * @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 @@ + + * + * 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 + * @author Joseph Bielawski + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author The Whole Life To Learn + * @author Manuel Reinhard + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * @author Manuel Reinhard + * @author Bernhard Schussek + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Antonio J. García Lagar + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Metadata for the LuhnValidator. + * + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Tim Nagel + * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/ + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/ + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"ANNOTATION"}) + * + * @author Bernhard Schussek + */ +class Optional extends Existence +{ +} diff --git a/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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * @author Joseph Bielawski + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"ANNOTATION"}) + * + * @author Bernhard Schussek + */ +class Required extends Existence +{ +} diff --git a/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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * @author Bernhard Schussek + */ +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 @@ + + * + * 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 + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 + * "|". "" is chosen if the passed $number is + * exactly 1. "" 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base BadMethodCallException for the Validator component. + * + * @author Bernhard Schussek + */ +class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/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 @@ + + * + * 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base ExceptionInterface for the Validator component. + * + * @author Bernhard Schussek + */ +interface ExceptionInterface +{ +} 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 @@ + + * + * 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base InvalidArgumentException for the Validator component. + * + * @author Bernhard Schussek + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * @author Bernhard Schussek + */ +class NoSuchMetadataException extends ValidatorException +{ +} diff --git a/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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base OutOfBoundsException for the Validator component. + * + * @author Bernhard Schussek + */ +class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface +{ +} diff --git a/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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base RuntimeException for the Validator component. + * + * @author Bernhard Schussek + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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: + * + *
+ * (Person)---($firstName: string)
+ *      \
+ *   ($address: Address)---($street: string)
+ * 
+ * + * We validate the Person 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: + * + *
+ * (Person)---($firstName: string)
+ *    ^ \
+ *   ($address: Address)---($street: string)
+ * 
+ * + * The validator is stopped at the Person node, both the root and the + * value (see {@link getValue}) of the context point to the Person + * instance. The property path is empty at this point (see {@link getPropertyPath}). + * The metadata of the context is the metadata of the Person node + * (see {@link getMetadata}). + * + * After advancing to the property $firstName of the Person + * instance, the state of the context looks like this: + * + *
+ * (Person)---($firstName: string)
+ *      \              ^
+ *   ($address: Address)---($street: string)
+ * 
+ * + * The validator is stopped at the property $firstName. The root still + * points to the Person 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 $address property and then to the + * $street property of the Address instance, the context state + * looks like this: + * + *
+ * (Person)---($firstName: string)
+ *      \
+ *   ($address: Address)---($street: string)
+ *                               ^
+ * 
+ * + * The validator is stopped at the property $street. The root still + * points to the Person 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 + * + * @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: + * + *
+     * (Person)---($address: Address)---($phoneNumber: PhoneNumber)
+     *                     ^
+     * 
+ * + * When the execution context stops at the Person instance, the + * property path is "address". When you validate the PhoneNumber + * instance now, pass "phoneNumber" as sub path to correct the property path + * to "address.phoneNumber": + * + *
+     * $context->validate($address->phoneNumber, 'phoneNumber');
+     * 
+ * + * 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 \Traversable. + * @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 $subPath to adapt the property path for the + * validated value. For example, take the following object graph: + * + *
+     * (Person)---($address: Address)---($street: string)
+     *                     ^
+     * 
+ * + * When the validator validates the Address instance, the + * property path stored in the execution context is "address". When you + * manually validate the property $street now, pass the sub path + * "street" to adapt the full property path to "address.street": + * + *
+     * $context->validate($address->street, new NotNull(), 'street');
+     * 
+ * + * @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: + * + *
+     * (Person)---($address: Address)---($street: string)
+     * 
+ * + * When the Person instance is passed to the validator, the + * property path is initially empty. When the $address property + * of that person is validated, the property path is "address". When + * the $street property of the related Address instance + * is validated, the property path is "address.street". + * + * Properties of objects are prefixed with a dot in the property path. + * Indices of arrays or objects implementing the {@link \ArrayAccess} + * interface are enclosed in brackets. For example, if the property in + * the previous example is $addresses and contains an array + * of Address instance, the property path generated for the + * $street property of one of these addresses is for example + * "addresses[0].street". + * + * @param string $subPath Optional. The suffix appended to the current + * property path. + * + * @return string The current property path. The result may be an empty + * string if the validator is currently validating the + * root value of the validation graph. + */ + public function getPropertyPath($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 @@ + + * + * 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: + * + *
    + *
  • 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.
  • + *
  • One single GlobalExecutionContextInterface stores the state + * that is independent of the current node.
  • + *
+ * + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * @author Fabien Potencier + */ +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 + * "", where is the non-namespaced name of the + * class. All constraints implicitly or explicitly assigned to group + * "Default" belong to both of these groups, unless the class defines + * a group sequence. + * + * If a class defines a group sequence, validating the class in "Default" + * will validate the group sequence. The constraints assigned to "Default" + * can still be validated by validating the class in "". + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Exception\MappingException; + +/** + * Base loader for loading validation metadata from a file. + * + * @author Bernhard Schussek + * + * @see YamlFileLoader + * @see XmlFileLoader + */ +abstract class FileLoader extends AbstractLoader +{ + /** + * 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +/** + * Base loader for loading validation metadata from a list of files. + * + * @author Bulat Shakirzyanov + * @author Bernhard Schussek + * + * @see YamlFilesLoader + * @see XmlFilesLoader + */ +abstract class FilesLoader extends LoaderChain +{ + /** + * Creates a new loader. + * + * @param array $paths An array of file paths + */ + public function __construct(array $paths) + { + parent::__construct($this->getFileLoaders($paths)); + } + + /** + * Returns an array of file loaders for the given file paths. + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Exception\MappingException; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata from multiple {@link LoaderInterface} instances. + * + * Pass the loaders when constructing the chain. Once + * {@link loadClassMetadata()} is called, that method will be called on all + * loaders in the chain. + * + * @author Bernhard Schussek + */ +class LoaderChain implements LoaderInterface +{ + /** + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata into {@link ClassMetadata} instances. + * + * @author Bernhard Schussek + */ +interface LoaderInterface +{ + /** + * Loads validation metadata into a {@link ClassMetadata} instance. + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Exception\MappingException; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata by calling a static method on the loaded class. + * + * @author Bernhard Schussek + */ +class StaticMethodLoader implements LoaderInterface +{ + /** + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +/** + * Loads validation metadata from a list of XML files. + * + * @author Bulat Shakirzyanov + * @author Bernhard Schussek + * + * @see FilesLoader + */ +class XmlFilesLoader extends FilesLoader +{ + /** + * {@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 @@ + + * + * 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 + */ +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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +/** + * Loads validation metadata from a list of YAML files. + * + * @author Bulat Shakirzyanov + * @author Bernhard Schussek + * + * @see FilesLoader + */ +class YamlFilesLoader extends FilesLoader +{ + /** + * {@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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Exception\ValidatorException; + +/** + * Stores all metadata needed for validating a class property. + * + * The value of the property is obtained by directly accessing the property. + * The property will be accessed by reflection, so the access of private and + * protected properties is supported. + * + * This class supports serialization and cloning. + * + * @author Bernhard Schussek + * + * @see PropertyMetadataInterface + */ +class PropertyMetadata extends MemberMetadata +{ + /** + * 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * PropertyMetadataInterface inherits from MetadataInterface, + * 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 + * accept() on all structurally related metadata instances. + * + * For example, to store constraints for PHP classes and their properties, + * create a class ClassMetadata (implementing MetadataInterface) + * and a class PropertyMetadata (implementing PropertyMetadataInterface). + * ClassMetadata::getPropertyMetadata($property) returns all + * PropertyMetadata instances for a property of that class. Its + * accept()-method simply forwards to ValidationVisitorInterface::visit() + * and calls accept() on all contained PropertyMetadata + * instances, which themselves call ValidationVisitorInterface::visit() + * again. + * + * @author Bernhard Schussek + * + * @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 + * accept()-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 @@ + + * + * 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 + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 + * + * @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 BadMethodCallException). + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + + + + + This value should be false. + Hierdie waarde moet vals wees. + + + This value should be true. + Hierdie waarde moet waar wees. + + + This value should be of type {{ type }}. + Hierdie waarde moet van die soort {{type}} wees. + + + This value should be blank. + Hierdie waarde moet leeg wees. + + + The value you selected is not a valid choice. + Die waarde wat jy gekies het is nie 'n geldige keuse nie. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Jy moet ten minste {{ limit }} kies.|Jy moet ten minste {{ limit }} keuses kies. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Jy moet by die meeste {{ limit }} keuse kies.|Jy moet by die meeste {{ limit }} keuses kies. + + + One or more of the given values is invalid. + Een of meer van die gegewe waardes is ongeldig. + + + This field was not expected. + Die veld is nie verwag nie. + + + This field is missing. + Hierdie veld ontbreek. + + + This value is not a valid date. + Hierdie waarde is nie 'n geldige datum nie. + + + This value is not a valid datetime. + Hierdie waarde is nie 'n geldige datum en tyd nie. + + + This value is not a valid email address. + Hierdie waarde is nie 'n geldige e-pos adres nie. + + + The file could not be found. + Die lêer kon nie gevind word nie. + + + The file is not readable. + Die lêer kan nie gelees word nie. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Die lêer is te groot ({{ size }} {{ suffix }}). Toegelaat maksimum grootte is {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Die MIME-tipe van die lêer is ongeldig ({{ type }}). Toegelaat MIME-tipes is {{ types }}. + + + This value should be {{ limit }} or less. + Hierdie waarde moet {{ limit }} of minder wees. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Hierdie waarde is te lank. Dit moet {{ limit }} karakter of minder wees.|Hierdie waarde is te lank. Dit moet {{ limit }} karakters of minder wees. + + + This value should be {{ limit }} or more. + Hierdie waarde moet {{ limit }} of meer wees. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Hierdie waarde is te kort. Dit moet {{ limit }} karakter of meer wees.|Hierdie waarde is te kort. Dit moet {{ limit }} karakters of meer wees. + + + This value should not be blank. + Hierdie waarde moet nie leeg wees nie. + + + This value should not be null. + Hierdie waarde moet nie nul wees nie. + + + This value should be null. + Hierdie waarde moet nul wees. + + + This value is not valid. + Hierdie waarde is nie geldig nie. + + + This value is not a valid time. + Hierdie waarde is nie 'n geldige tyd nie. + + + This value is not a valid URL. + Hierdie waarde is nie 'n geldige URL nie. + + + The two values should be equal. + Die twee waardes moet gelyk wees. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Die lêer is te groot. Toegelaat maksimum grootte is {{ limit }} {{ suffix }}. + + + The file is too large. + Die lêer is te groot. + + + The file could not be uploaded. + Die lêer kan nie opgelaai word nie. + + + This value should be a valid number. + Hierdie waarde moet 'n geldige nommer wees. + + + This file is not a valid image. + Hierdie lêer is nie 'n geldige beeld nie. + + + This is not a valid IP address. + Hierdie is nie 'n geldige IP-adres nie. + + + This value is not a valid language. + Hierdie waarde is nie 'n geldige taal nie. + + + This value is not a valid locale. + Hierdie waarde is nie 'n geldige land instelling nie. + + + This value is not a valid country. + Hierdie waarde is nie 'n geldige land nie. + + + This value is already used. + Hierdie waarde word reeds gebruik. + + + The size of the image could not be detected. + Die grootte van die beeld kon nie opgespoor word nie. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Die beeld breedte is te groot ({{ width }}px). Toegelaat maksimum breedte is {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Die beeld breedte is te klein ({{ width }}px). Minimum breedte verwag is {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Die beeld hoogte is te groot ({{ height }}px). Toegelaat maksimum hoogte is {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Die beeld hoogte is te klein ({{ height }}px). Minimum hoogte verwag is {{ min_height }}px. + + + This value should be the user's current password. + Hierdie waarde moet die huidige wagwoord van die gebruiker wees. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Hierdie waarde moet presies {{ limit }} karakter wees.|Hierdie waarde moet presies {{ limit }} karakters wees. + + + The file was only partially uploaded. + Die lêer is slegs gedeeltelik opgelaai. + + + No file was uploaded. + Geen lêer is opgelaai nie. + + + No temporary folder was configured in php.ini. + Geen tydelike lêer is ingestel in php.ini nie. + + + Cannot write temporary file to disk. + Kan nie tydelike lêer skryf op skyf nie. + + + A PHP extension caused the upload to fail. + 'n PHP-uitbreiding veroorsaak die oplaai van die lêer om te misluk. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Hierdie versameling moet {{ limit }} element of meer bevat.|Hierdie versameling moet {{ limit }} elemente of meer bevat. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Hierdie versameling moet {{ limit }} element of minder bevat.|Hierdie versameling moet {{ limit }} elemente of meer bevat. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Hierdie versameling moet presies {{ limit }} element bevat.|Hierdie versameling moet presies {{ limit }} elemente bevat. + + + Invalid card number. + Ongeldige kredietkaart nommer. + + + Unsupported card type or invalid card number. + Nie-ondersteunde tipe kaart of ongeldige kredietkaart nommer. + + + + 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 @@ + + + + + + This value should be false. + هذه القيمة يجب أن تكون خاطئة. + + + This value should be true. + هذه القيمة يجب أن تكون حقيقية. + + + This value should be of type {{ type }}. + هذه القيمة يجب ان تكون من نوع {{ type }}. + + + This value should be blank. + هذه القيمة يجب ان تكون فارغة. + + + The value you selected is not a valid choice. + القيمة المختارة ليست خيارا صحيحا. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيارات على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيارات على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر. + + + One or more of the given values is invalid. + واحد أو أكثر من القيم المعطاه خاطئ. + + + This field was not expected. + لم يكن من المتوقع هذا المجال. + + + This field is missing. + هذا المجال مفقود. + + + This value is not a valid date. + هذه القيمة ليست تاريخا صالحا. + + + This value is not a valid datetime. + هذه القيمة ليست تاريخا و وقتا صالحا. + + + This value is not a valid email address. + هذه القيمة ليست عنوان بريد إلكتروني صحيح. + + + The file could not be found. + لا يمكن العثور على الملف. + + + The file is not readable. + الملف غير قابل للقراءة. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + الملف كبير جدا ({{ size }} {{ suffix }}).اقصى مساحه مسموح بها ({{ limit }} {{ suffix }}). + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + نوع الملف غير صحيح ({{ type }}). الانواع المسموح بها هى {{ types }}. + + + This value should be {{ limit }} or less. + هذه القيمة يجب ان تكون {{ limit }} او اقل. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حروف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل. + + + This value should be {{ limit }} or more. + هذه القيمة يجب ان تكون {{ limit }} او اكثر. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حروف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر. + + + This value should not be blank. + هذه القيمة يجب الا تكون فارغة. + + + This value should not be null. + هذه القيمة يجب الا تكون فارغة. + + + This value should be null. + هذه القيمة يجب ان تكون فارغة. + + + This value is not valid. + هذه القيمة غير صحيحة. + + + This value is not a valid time. + هذه القيمة ليست وقت صحيح. + + + This value is not a valid URL. + هذه القيمة ليست رابط الكترونى صحيح. + + + The two values should be equal. + القيمتان يجب ان تكونا متساويتان. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + الملف كبير جدا. اقصى مساحه مسموح بها {{ limit }} {{ suffix }}. + + + The file is too large. + الملف كبير جدا. + + + The file could not be uploaded. + لم استطع استقبال الملف. + + + This value should be a valid number. + هذه القيمة يجب ان تكون رقم. + + + This file is not a valid image. + هذا الملف ليس صورة صحيحة. + + + This is not a valid IP address. + هذه القيمة ليست عنوان رقمى صحيح. + + + This value is not a valid language. + هذه القيمة ليست لغة صحيحة. + + + This value is not a valid locale. + هذه القيمة ليست موقع صحيح. + + + This value is not a valid country. + هذه القيمة ليست بلدا صالحا. + + + This value is already used. + هذه القيمة مستخدمة بالفعل. + + + The size of the image could not be detected. + لم استطع معرفة حجم الصورة. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + عرض الصورة كبير جدا ({{ width }}px). اقصى عرض مسموح به هو{{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + عرض الصورة صغير جدا ({{ width }}px). اقل عرض مسموح به هو{{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + طول الصورة كبير جدا ({{ height }}px). اقصى طول مسموح به هو{{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + طول الصورة صغير جدا ({{ height }}px). اقل طول مسموح به هو{{ min_height }}px. + + + This value should be the user's current password. + هذه القيمة يجب ان تكون كلمة سر المستخدم الحالية. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حروف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط. + + + The file was only partially uploaded. + تم استقبال جزء من الملف فقط. + + + No file was uploaded. + لم يتم ارسال اى ملف. + + + No temporary folder was configured in php.ini. + لم يتم تهيئة حافظة مؤقتة فى ملف php.ini. + + + Cannot write temporary file to disk. + لم استطع كتابة الملف المؤقت. + + + A PHP extension caused the upload to fail. + احد اضافات PHP تسببت فى فشل استقبال الملف. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط. + + + Invalid card number. + رقم البطاقه غير صحيح. + + + Unsupported card type or invalid card number. + نوع البطاقه غير مدعوم او الرقم غير صحيح. + + + This is not a valid International Bank Account Number (IBAN). + الرقم IBAN (رقم الحساب المصرفي الدولي) الذي تم إدخاله غير صالح. + + + This value is not a valid ISBN-10. + هذه القيمة ليست ISBN-10 صالحة. + + + This value is not a valid ISBN-13. + هذه القيمة ليست ISBN-13 صالحة. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + هذه القيمة ليست ISBN-10 صالحة ولا ISBN-13 صالحة. + + + This value is not a valid ISSN. + هذه القيمة ليست ISSN صالحة. + + + This value is not a valid currency. + العُملة غير صحيحة. + + + This value should be equal to {{ compared_value }}. + القيمة يجب ان تساوي {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + القيمة يجب ان تكون اعلي من {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + القيمة يجب ان تكون مساوية او اعلي من {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + القيمة يجب ان تطابق {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + القيمة يجب ان تكون اقل من {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + القيمة يجب ان تساوي او تقل عن {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + القيمة يجب ان لا تساوي {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + القيمة يجب ان لا تطابق {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + Bu dəyər false olmalıdır. + + + This value should be true. + Bu dəyər true olmalıdır. + + + This value should be of type {{ type }}. + Bu dəyərin tipi {{ type }} olmalıdır. + + + This value should be blank. + Bu dəyər boş olmalıdır. + + + The value you selected is not a valid choice. + Seçdiyiniz dəyər düzgün bir seçim değil. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Ən az {{ limit }} seçim qeyd edilməlidir. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Ən çox {{ limit }} seçim qeyd edilməlidir. + + + One or more of the given values is invalid. + Təqdim edilən dəyərlərdən bir və ya bir neçəsi yanlışdır. + + + This field was not expected. + Bu sahə gözlənilmirdi. + + + This field is missing. + Bu sahə əksikdir. + + + This value is not a valid date. + Bu dəyər düzgün bir tarix deyil. + + + This value is not a valid datetime. + Bu dəyər düzgün bir tarixsaat deyil. + + + This value is not a valid email address. + Bu dəyər düzgün bir e-poçt adresi deyil. + + + The file could not be found. + Fayl tapılmadı. + + + The file is not readable. + Fayl oxunabilən deyil. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fayl çox böyükdür ({{ size }} {{ suffix }}). İcazə verilən maksimum fayl ölçüsü {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Faylın mime tipi yanlışdr ({{ type }}). İcazə verilən mime tipləri {{ types }}. + + + This value should be {{ limit }} or less. + Bu dəyər {{ limit }} və ya altında olmalıdır. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Bu dəyər çox uzundur. {{ limit }} və ya daha az simvol olmalıdır. + + + This value should be {{ limit }} or more. + Bu dəyər {{ limit }} veya daha fazla olmalıdır. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Bu dəyər çox qısadır. {{ limit }} və ya daha çox simvol olmalıdır. + + + This value should not be blank. + Bu dəyər boş olmamalıdır. + + + This value should not be null. + Bu dəyər boş olmamalıdır. + + + This value should be null. + Bu dəyər boş olmamalıdır. + + + This value is not valid. + Bu dəyər doğru deyil. + + + This value is not a valid time. + Bu dəyər doğru bir saat deyil. + + + This value is not a valid URL. + Bu dəyər doğru bir URL değil. + + + The two values should be equal. + İki dəyər eyni olmalıdır. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fayl çox böyükdür. İcazə verilən ən böyük fayl ölçüsü {{ limit }} {{ suffix }}. + + + The file is too large. + Fayl çox böyükdür. + + + The file could not be uploaded. + Fayl yüklənəbilmir. + + + This value should be a valid number. + Bu dəyər rəqəm olmalıdır. + + + This file is not a valid image. + Bu fayl düzgün bir şəkil deyil. + + + This is not a valid IP address. + Bu düzgün bir IP adresi deyil. + + + This value is not a valid language. + Bu dəyər düzgün bir dil deyil. + + + This value is not a valid locale. + Bu dəyər düzgün bir dil deyil. + + + This value is not a valid country. + Bu dəyər düzgün bir ölkə deyil. + + + This value is already used. + Bu dəyər hal-hazırda istifadədədir. + + + The size of the image could not be detected. + Şəklin ölçüsü hesablana bilmir. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Şəklin genişliyi çox böyükdür ({{ width }}px). İcazə verilən ən böyük genişlik {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Şəklin genişliyi çox kiçikdir ({{ width }}px). Ən az {{ min_width }}px olmalıdır. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Şəklin yüksəkliyi çox böyükdür ({{ height }}px). İcazə verilən ən böyük yüksəklik {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Şəklin yüksəkliyi çox kiçikdir ({{ height }}px). Ən az {{ min_height }}px olmalıdır. + + + This value should be the user's current password. + Bu dəyər istifadəçinin hazırkı parolu olmalıdır. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Bu dəyər tam olaraq {{ limit }} simvol olmaldır. + + + The file was only partially uploaded. + Fayl qismən yükləndi. + + + No file was uploaded. + Fayl yüklənmədi. + + + No temporary folder was configured in php.ini. + php.ini'də müvəqqəti qovluq quraşdırılmayıb. + + + Cannot write temporary file to disk. + Müvəqqəti fayl diskə yazıla bilmir. + + + A PHP extension caused the upload to fail. + Bir PHP əlavəsi faylın yüklənməsinə mane oldu. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Bu kolleksiyada {{ limit }} və ya daha çox element olmalıdır. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Bu kolleksiyada {{ limit }} və ya daha az element olmalıdır. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Bu kolleksiyada tam olaraq {{ limit }} element olmalıdır. + + + Invalid card number. + Yanlış kart nömrəsi. + + + Unsupported card type or invalid card number. + Dəstəklənməyən kart tipi və ya yanlış kart nömrəsi. + + + + 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 @@ + + + + + + This value should be false. + Стойността трябва да бъде лъжа (false). + + + This value should be true. + Стойността трябва да бъде истина (true). + + + This value should be of type {{ type }}. + Стойността трябва да бъде от тип {{ type }}. + + + This value should be blank. + Стойността трябва да бъде празна. + + + The value you selected is not a valid choice. + Избраната стойност е невалидна. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Трябва да изберете поне {{ limit }} опция.|Трябва да изберете поне {{ limit }} опции. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Трябва да изберете най-много {{ limit }} опция.|Трябва да изберете най-много {{ limit }} опции. + + + One or more of the given values is invalid. + Една или повече от зададените стойности е невалидна. + + + This field was not expected. + Това поле не се е очаквало. + + + This field is missing. + Това поле липсва. + + + This value is not a valid date. + Стойността не е валидна дата (date). + + + This value is not a valid datetime. + Стойността не е валидна дата (datetime). + + + This value is not a valid email address. + Стойността не е валиден email адрес. + + + The file could not be found. + Файлът не беше открит. + + + The file is not readable. + Файлът не може да бъде прочетен. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файлът е твърде голям ({{ size }} {{ suffix }}). Максималният размер е {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Майм типа на файла е невалиден ({{ type }}). Разрешени майм типове са {{ types }}. + + + This value should be {{ limit }} or less. + Стойността трябва да бъде {{ limit }} или по-малко. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Стойността е твърде дълга. Трябва да съдържа най-много {{ limit }} символ.|Стойността е твърде дълга. Трябва да съдържа най-много {{ limit }} символа. + + + This value should be {{ limit }} or more. + Стойността трябва да бъде {{ limit }} или повече. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Стойността е твърде кратка. Трябва да съдържа поне {{ limit }} символ.|Стойността е твърде кратка. Трябва да съдържа поне {{ limit }} символа. + + + This value should not be blank. + Стойността не трябва да бъде празна. + + + This value should not be null. + Стойността не трябва да бъде null. + + + This value should be null. + Стойността трябва да бъде null. + + + This value is not valid. + Стойността не е валидна. + + + This value is not a valid time. + Стойността не е валидно време (time). + + + This value is not a valid URL. + Стойността не е валиден URL. + + + The two values should be equal. + Двете стойности трябва да бъдат равни. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файлът е твърде голям. Разрешеният максимален размер е {{ limit }} {{ suffix }}. + + + The file is too large. + Файлът е твърде голям. + + + The file could not be uploaded. + Файлът не може да бъде качен. + + + This value should be a valid number. + Стойността трябва да бъде валиден номер. + + + This file is not a valid image. + Файлът не е валидно изображение. + + + This is not a valid IP address. + Това не е валиден IP адрес. + + + This value is not a valid language. + Стойността не е валиден език. + + + This value is not a valid locale. + Стойността не е валидна локализация. + + + This value is not a valid country. + Стойността не е валидна държава. + + + This value is already used. + Стойността вече е в употреба. + + + The size of the image could not be detected. + Размера на изображението не може да бъде определен. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Изображението е твърде широко ({{ width }}px). Широчината трябва да бъде максимум {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Изображението е с твърде малка широчина ({{ width }}px). Широчината трябва да бъде минимум {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Изображението е с твърде голяма височина ({{ height }}px). Височината трябва да бъде максимум {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Изображението е с твърде малка височина ({{ height }}px). Височина трябва да бъде минимум {{ min_height }}px. + + + This value should be the user's current password. + Стойността трябва да бъде текущата потребителска парола. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Стойността трябва да бъде точно {{ limit }} символ.|Стойността трябва да бъде точно {{ limit }} символа. + + + The file was only partially uploaded. + Файлът е качен частично. + + + No file was uploaded. + Файлът не беше качен. + + + No temporary folder was configured in php.ini. + Не е посочена директория за временни файлове в php.ini. + + + Cannot write temporary file to disk. + Не може да запише временен файл на диска. + + + A PHP extension caused the upload to fail. + PHP разширение предизвика прекъсване на качването. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Колекцията трябва да съдържа поне {{ limit }} елемент.|Колекцията трябва да съдържа поне {{ limit }} елемента. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Колекцията трябва да съдържа най-много {{ limit }} елемент.|Колекцията трябва да съдържа най-много {{ limit }} елемента. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Колекцията трябва да съдържа точно {{ limit }} елемент.|Колекцията трябва да съдържа точно {{ limit }} елемента. + + + Invalid card number. + Невалиден номер на картата. + + + Unsupported card type or invalid card number. + Неподдържан тип карта или невалиден номер на картата. + + + This is not a valid International Bank Account Number (IBAN). + Невалиден Международен номер на банкова сметка (IBAN). + + + This value is not a valid ISBN-10. + Невалиден ISBN-10. + + + This value is not a valid ISBN-13. + Невалиден ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Невалидна стойност както за ISBN-10, така и за ISBN-13 . + + + This value is not a valid ISSN. + Невалиден Международен стандартен сериен номер (ISSN). + + + This value is not a valid currency. + Невалидна валута. + + + This value should be equal to {{ compared_value }}. + Стойността трябва да бъде равна на {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Стойността трябва да бъде по-голяма от {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Стойността трябва да бъде по-голяма или равна на {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Стойността трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Стойността трябва да бъде по-малка {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Стойността трябва да бъде по-малка или равна на {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Стойността не трябва да бъде равна на {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Стойността не трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + Aquest valor hauria de ser fals. + + + This value should be true. + Aquest valor hauria de ser cert. + + + This value should be of type {{ type }}. + Aquest valor hauria de ser del tipus {{ type }}. + + + This value should be blank. + Aquest valor hauria d'estar buit. + + + The value you selected is not a valid choice. + El valor seleccionat no és una opció vàlida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Ha de seleccionar almenys {{ limit }} opció.|Ha de seleccionar almenys {{ limit }} opcions. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Ha de seleccionar com a màxim {{ limit }} opció.|Ha de seleccionar com a màxim {{ limit }} opcions. + + + One or more of the given values is invalid. + Un o més dels valors facilitats són incorrectes. + + + This field was not expected. + Aquest camp no s'esperava. + + + This field is missing. + Aquest camp està desaparegut. + + + This value is not a valid date. + Aquest valor no és una data vàlida. + + + This value is not a valid datetime. + Aquest valor no és una data i hora vàlida. + + + This value is not a valid email address. + Aquest valor no és una adreça d'email vàlida. + + + The file could not be found. + No s'ha pogut trobar l'arxiu. + + + The file is not readable. + No es pot llegir l'arxiu. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + L'arxiu és massa gran ({{ size }} {{ suffix }}). La grandària màxima permesa és {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + El tipus mime de l'arxiu no és vàlid ({{ type }}). Els tipus mime vàlids són {{ types }}. + + + This value should be {{ limit }} or less. + Aquest valor hauria de ser {{ limit }} o menys. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Aquest valor és massa llarg. Hauria de tenir {{ limit }} caràcter o menys.|Aquest valor és massa llarg. Hauria de tenir {{ limit }} caràcters o menys. + + + This value should be {{ limit }} or more. + Aquest valor hauria de ser {{ limit }} o més. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Aquest valor és massa curt. Hauria de tenir {{ limit }} caràcters o més. + + + This value should not be blank. + Aquest valor no hauria d'estar buit. + + + This value should not be null. + Aquest valor no hauria de ser null. + + + This value should be null. + Aquest valor hauria de ser null. + + + This value is not valid. + Aquest valor no és vàlid. + + + This value is not a valid time. + Aquest valor no és una hora vàlida. + + + This value is not a valid URL. + Aquest valor no és una URL vàlida. + + + The two values should be equal. + Els dos valors haurien de ser iguals. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + L'arxiu és massa gran. El tamany màxim permés és {{ limit }} {{ suffix }}. + + + The file is too large. + L'arxiu és massa gran. + + + The file could not be uploaded. + No es pot pujar l'arxiu. + + + This value should be a valid number. + Aquest valor hauria de ser un nombre vàlid. + + + This file is not a valid image. + L'arxiu no és una imatge vàlida. + + + This is not a valid IP address. + Això no és una adreça IP vàlida. + + + This value is not a valid language. + Aquest valor no és un idioma vàlid. + + + This value is not a valid locale. + Aquest valor no és una localització vàlida. + + + This value is not a valid country. + Aquest valor no és un país vàlid. + + + This value is already used. + Aquest valor ja s'ha utilitzat. + + + The size of the image could not be detected. + No s'ha pogut determinar la grandària de la imatge. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + L'amplària de la imatge és massa gran ({{ width }}px). L'amplària màxima permesa són {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + L'amplària de la imatge és massa petita ({{ width }}px). L'amplària mínima requerida són {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + L'altura de la imatge és massa gran ({{ height }}px). L'altura màxima permesa són {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + L'altura de la imatge és massa petita ({{ height }}px). L'altura mínima requerida són {{ min_height }}px. + + + This value should be the user's current password. + Aquest valor hauria de ser la contrasenya actual de l'usuari. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Aquest valor hauria de tenir exactament {{ limit }} caràcter.|Aquest valor hauria de tenir exactament {{ limit }} caràcters. + + + The file was only partially uploaded. + L'arxiu va ser només pujat parcialment. + + + No file was uploaded. + Cap arxiu va ser pujat. + + + No temporary folder was configured in php.ini. + Cap carpeta temporal va ser configurada en php.ini. + + + Cannot write temporary file to disk. + No es va poder escriure l'arxiu temporal en el disc. + + + A PHP extension caused the upload to fail. + Una extensió de PHP va fer que la pujada fallara. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Aquesta col·lecció ha de contenir {{ limit }} element o més.|Aquesta col·lecció ha de contenir {{ limit }} elements o més. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Aquesta col·lecció ha de contenir {{ limit }} element o menys.|Aquesta col·lecció ha de contenir {{ limit }} elements o menys. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Aquesta col·lecció ha de contenir exactament {{ limit }} element.|Aquesta col·lecció ha de contenir exactament {{ limit }} elements. + + + Invalid card number. + Número de targeta invàlid. + + + Unsupported card type or invalid card number. + Tipus de targeta no suportada o número de targeta invàlid. + + + This is not a valid International Bank Account Number (IBAN). + Això no és un nombre de compte bancari internacional (IBAN) vàlid. + + + This value is not a valid ISBN-10. + Aquest valor no és un ISBN-10 vàlid. + + + This value is not a valid ISBN-13. + Aquest valor no és un ISBN-13 vàlid. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Aquest valor no és ni un ISBN-10 vàlid ni un ISBN-13 vàlid. + + + This value is not a valid ISSN. + Aquest valor no és un ISSN vàlid. + + + This value is not a valid currency. + Aquest valor no és una divisa vàlida. + + + This value should be equal to {{ compared_value }}. + Aquest valor hauria de ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Aquest valor hauria de ser més gran a {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Aquest valor hauria de ser major o igual a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Aquest valor hauria de ser idèntic a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Aquest valor hauria de ser menor a {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Aquest valor hauria de ser menor o igual a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Aquest valor no hauria de ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Aquest valor no hauria de idèntic a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + La proporció de l'imatge és massa gran ({{ ratio }}). La màxima proporció permesa és {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + La proporció de l'imatge és massa petita ({{ ratio }}). La mínima proporció permesa és {{ max_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + L'imatge és quadrada({{ width }}x{{ height }}px). Les imatges quadrades no estan permeses. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + L'imatge està orientada horitzontalment ({{ width }}x{{ height }}px). Les imatges orientades horitzontalment no estan permeses. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + L'imatge està orientada verticalment ({{ width }}x{{ height }}px). Les imatges orientades verticalment no estan permeses. + + + An empty file is not allowed. + No està permès un fixter buit. + + + + 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 @@ + + + + + + This value should be false. + Tato hodnota musí být nepravdivá (false). + + + This value should be true. + Tato hodnota musí být pravdivá (true). + + + This value should be of type {{ type }}. + Tato hodnota musí být typu {{ type }}. + + + This value should be blank. + Tato hodnota musí být prázdná. + + + The value you selected is not a valid choice. + Vybraná hodnota není platnou možností. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Musí být vybrána nejméně {{ limit }} možnost.|Musí být vybrány nejméně {{ limit }} možnosti.|Musí být vybráno nejméně {{ limit }} možností. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Musí být vybrána maximálně {{ limit }} možnost.|Musí být vybrány maximálně {{ limit }} možnosti.|Musí být vybráno maximálně {{ limit }} možností. + + + One or more of the given values is invalid. + Některé z uvedených hodnot jsou neplatné. + + + This field was not expected. + Toto pole nebyla očekávána. + + + This field is missing. + Toto pole chybí. + + + This value is not a valid date. + Tato hodnota není platné datum. + + + This value is not a valid datetime. + Tato hodnota není platné datum s časovým údajem. + + + This value is not a valid email address. + Tato hodnota není platná e-mailová adresa. + + + The file could not be found. + Soubor nebyl nalezen. + + + The file is not readable. + Soubor je nečitelný. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Soubor je příliš velký ({{ size }} {{ suffix }}). Maximální povolená velikost souboru je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Neplatný mime typ souboru ({{ type }}). Povolené mime typy souborů jsou {{ types }}. + + + This value should be {{ limit }} or less. + Tato hodnota musí být {{ limit }} nebo méně. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Tato hodnota je příliš dlouhá. Musí obsahovat maximálně {{ limit }} znak.|Tato hodnota je příliš dlouhá. Musí obsahovat maximálně {{ limit }} znaky.|Tato hodnota je příliš dlouhá. Musí obsahovat maximálně {{ limit }} znaků. + + + This value should be {{ limit }} or more. + Tato hodnota musí být {{ limit }} nebo více. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Tato hodnota je příliš krátká. Musí obsahovat minimálně {{ limit }} znak.|Tato hodnota je příliš krátká. Musí obsahovat minimálně {{ limit }} znaky.|Tato hodnota je příliš krátká. Musí obsahovat minimálně {{ limit }} znaků. + + + This value should not be blank. + Tato hodnota nesmí být prázdná. + + + This value should not be null. + Tato hodnota nesmí být null. + + + This value should be null. + Tato hodnota musí být null. + + + This value is not valid. + Tato hodnota není platná. + + + This value is not a valid time. + Tato hodnota není platný časový údaj. + + + This value is not a valid URL. + Tato hodnota není platná URL adresa. + + + The two values should be equal. + Tyto dvě hodnoty musí být stejné. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Soubor je příliš velký. Maximální povolená velikost souboru je {{ limit }} {{ suffix }}. + + + The file is too large. + Soubor je příliš velký. + + + The file could not be uploaded. + Soubor se nepodařilo nahrát. + + + This value should be a valid number. + Tato hodnota musí být číslo. + + + This file is not a valid image. + Tento soubor není obrázek. + + + This is not a valid IP address. + Toto není platná IP adresa. + + + This value is not a valid language. + Tento jazyk neexistuje. + + + This value is not a valid locale. + Tato lokalizace neexistuje. + + + This value is not a valid country. + Tato země neexistuje. + + + This value is already used. + Tato hodnota je již používána. + + + The size of the image could not be detected. + Nepodařily se zjistit rozměry obrázku. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Obrázek je příliš široký ({{ width }}px). Maximální povolená šířka obrázku je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Obrázek je příliš úzký ({{ width }}px). Minimální šířka musí být {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Obrázek je příliš vysoký ({{ height }}px). Maximální povolená výška obrázku je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Obrázek je příliš nízký ({{ height }}px). Minimální výška obrázku musí být {{ min_height }}px. + + + This value should be the user's current password. + Tato hodnota musí být aktuální heslo uživatele. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Tato hodnota musí mít přesně {{ limit }} znak.|Tato hodnota musí mít přesně {{ limit }} znaky.|Tato hodnota musí mít přesně {{ limit }} znaků. + + + The file was only partially uploaded. + Byla nahrána jen část souboru. + + + No file was uploaded. + Žádný soubor nebyl nahrán. + + + No temporary folder was configured in php.ini. + V php.ini není nastavena cesta k adresáři pro dočasné soubory. + + + Cannot write temporary file to disk. + Dočasný soubor se nepodařilo zapsat na disk. + + + A PHP extension caused the upload to fail. + Rozšíření PHP zabránilo nahrání souboru. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Tato kolekce musí obsahovat minimálně {{ limit }} prvek.|Tato kolekce musí obsahovat minimálně {{ limit }} prvky.|Tato kolekce musí obsahovat minimálně {{ limit }} prvků. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Tato kolekce musí obsahovat maximálně {{ limit }} prvek.|Tato kolekce musí obsahovat maximálně {{ limit }} prvky.|Tato kolekce musí obsahovat maximálně {{ limit }} prvků. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Tato kolekce musí obsahovat přesně {{ limit }} prvek.|Tato kolekce musí obsahovat přesně {{ limit }} prvky.|Tato kolekce musí obsahovat přesně {{ limit }} prvků. + + + Invalid card number. + Neplatné číslo karty. + + + Unsupported card type or invalid card number. + Nepodporovaný typ karty nebo neplatné číslo karty. + + + This is not a valid International Bank Account Number (IBAN). + Toto je neplatný IBAN. + + + This value is not a valid ISBN-10. + Tato hodnota není platné ISBN-10. + + + This value is not a valid ISBN-13. + Tato hodnota není platné ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Tato hodnota není platné ISBN-10 ani ISBN-13. + + + This value is not a valid ISSN. + Tato hodnota není platné ISSN. + + + This value is not a valid currency. + Tato měna neexistuje. + + + This value should be equal to {{ compared_value }}. + Tato hodnota musí být rovna {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Tato hodnota musí být větší než {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Tato hodnota musí být větší nebo rovna {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Tato hodnota musí být typu {{ compared_value_type }} a zároveň musí být rovna {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Tato hodnota musí být menší než {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Tato hodnota musí být menší nebo rovna {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Tato hodnota nesmí být rovna {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Tato hodnota nesmí být typu {{ compared_value_type }} a zároveň nesmí být rovna {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Poměr stran obrázku je příliš velký ({{ ratio }}). Maximální povolený poměr stran obrázku je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Poměr stran obrázku je příliš malý ({{ ratio }}). Minimální povolený poměr stran obrázku je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Strany obrázku jsou čtvercové ({{ width }}x{{ height }}px). Čtvercové obrázky nejsou povolené. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Obrázek je orientovaný na šířku ({{ width }}x{{ height }}px). Obrázky orientované na šířku nejsou povolené. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Obrázek je orientovaný na výšku ({{ width }}x{{ height }}px). Obrázky orientované na výšku nejsou povolené. + + + An empty file is not allowed. + Soubor nesmí být prázdný. + + + + 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 @@ + + + + + + This value should be false. + Dylid bod y gwerth hwn yn ffug. + + + This value should be true. + Dylid bod y gwerth hwn yn wir. + + + This value should be of type {{ type }}. + Dylid bod y gwerth hwn bod o fath {{ type }}. + + + This value should be blank. + Dylid bod y gwerth hwn yn wag. + + + The value you selected is not a valid choice. + Nid yw'r gwerth â ddewiswyd yn ddilys. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Rhaid dewis o leiaf {{ limit }} opsiwn. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Rhaid dewis dim mwy na {{ limit }} opsiwn. + + + One or more of the given values is invalid. + Mae un neu fwy o'r gwerthoedd a roddwyd yn annilys. + + + This field was not expected. + Nid oedd disgwyl y maes hwn. + + + This field is missing. + Mae'r maes hwn ar goll. + + + This value is not a valid date. + Nid yw'r gwerth yn ddyddiad dilys. + + + This value is not a valid datetime. + Nid yw'r gwerth yn datetime dilys. + + + This value is not a valid email address. + Nid yw'r gwerth yn gyfeiriad ebost dilys. + + + The file could not be found. + Ni ddarganfyddwyd y ffeil. + + + The file is not readable. + Ni ellir darllen y ffeil. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Mae'r ffeil yn rhy fawr ({{ size }} {{ suffix }}). Yr uchafswm â ganiateir yw {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Nid yw math mime y ffeil yn ddilys ({{ type }}). Dyma'r mathau â ganiateir {{ types }}. + + + This value should be {{ limit }} or less. + Dylai'r gwerth hwn fod yn {{ limit }} neu lai. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Mae'r gwerth hwn rhy hir. Dylai gynnwys {{ limit }} nodyn cyfrifiadurol neu lai. + + + This value should be {{ limit }} or more. + Dylai'r gwerth hwn fod yn {{ limit }} neu fwy. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Mae'r gwerth hwn yn rhy fyr. Dylai gynnwys {{ limit }} nodyn cyfrifiadurol neu fwy. + + + This value should not be blank. + Ni ddylai'r gwerth hwn fod yn wag. + + + This value should not be null. + Ni ddylai'r gwerth hwn fod yn null. + + + This value should be null. + Dylai'r gwerth fod yn null. + + + This value is not valid. + Nid yw'r gwerth hwn yn ddilys. + + + This value is not a valid time. + Nid yw'r gwerth hwn yn amser dilys. + + + This value is not a valid URL. + Nid yw'r gwerth hwn yn URL dilys. + + + The two values should be equal. + Rhaid i'r ddau werth fod yn gyfystyr a'u gilydd. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Mae'r ffeil yn rhy fawr. Yr uchafswm â ganiateir yw {{ limit }} {{ suffix }}. + + + The file is too large. + Mae'r ffeil yn rhy fawr. + + + The file could not be uploaded. + Methwyd ag uwchlwytho'r ffeil. + + + This value should be a valid number. + Dylai'r gwerth hwn fod yn rif dilys. + + + This file is not a valid image. + Nid yw'r ffeil hon yn ddelwedd dilys. + + + This is not a valid IP address. + Nid yw hwn yn gyfeiriad IP dilys. + + + This value is not a valid language. + Nid yw'r gwerth hwn yn iaith ddilys. + + + This value is not a valid locale. + Nid yw'r gwerth hwn yn locale dilys. + + + This value is not a valid country. + Nid yw'r gwerth hwn yn wlad dilys. + + + This value is already used. + Mae'r gwerth hwn eisoes yn cael ei ddefnyddio. + + + The size of the image could not be detected. + Methwyd â darganfod maint y ddelwedd. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Mae lled y ddelwedd yn rhy fawr ({{ width }}px). Y lled mwyaf â ganiateir yw {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Mae lled y ddelwedd yn rhy fach ({{ width }}px). Y lled lleiaf â ganiateir yw {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Mae uchder y ddelwedd yn rhy fawr ({{ width }}px). Yr uchder mwyaf â ganiateir yw {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Mae uchder y ddelwedd yn rhy fach ({{ width }}px). Yr uchder lleiaf â ganiateir yw {{ min_height }}px. + + + This value should be the user's current password. + Dylaid bod y gwerth hwn yn gyfrinair presenol y defnyddiwr. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Dylai'r gwerth hwn fod yn union {{ limit }} nodyn cyfrifiadurol o hyd. + + + The file was only partially uploaded. + Dim ond rhan o'r ffeil ag uwchlwythwyd. + + + No file was uploaded. + Ni uwchlwythwyd unrhyw ffeil. + + + No temporary folder was configured in php.ini. + Nid oes ffolder dros-dro wedi'i gosod yn php.ini. + + + Cannot write temporary file to disk. + Methwyd ag ysgrifennu'r ffeil dros-dro ar ddisg. + + + A PHP extension caused the upload to fail. + Methwyd ag uwchlwytho oherwydd ategyn PHP. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Dylai'r casgliad hwn gynnwys {{ limit }} elfen neu fwy. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Dylai'r casgliad hwn gynnwys {{ limit }} elfen neu lai. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Dylai'r casgliad hwn gynnwys union {{ limit }} elfen. + + + Invalid card number. + Nid oedd rhif y cerdyn yn ddilys. + + + Unsupported card type or invalid card number. + Unai ni dderbynir y math yna o gerdyn, neu nid yw rhif y cerdyn yn ddilys. + + + + 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 @@ + + + + + + This value should be false. + Værdien skal være falsk. + + + This value should be true. + Værdien skal være sand. + + + This value should be of type {{ type }}. + Værdien skal være af typen {{ type }}. + + + This value should be blank. + Værdien skal være blank. + + + The value you selected is not a valid choice. + Værdien skal være en af de givne muligheder. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du skal vælge mindst {{ limit }} muligheder. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan højest vælge {{ limit }} muligheder. + + + One or more of the given values is invalid. + En eller flere af de oplyste værdier er ugyldige. + + + This field was not expected. + Feltet blev ikke forventet. + + + This field is missing. + Dette felt er mangler. + + + This value is not a valid date. + Værdien er ikke en gyldig dato. + + + This value is not a valid datetime. + Værdien er ikke en gyldig dato og tid. + + + This value is not a valid email address. + Værdien er ikke en gyldig e-mail adresse. + + + The file could not be found. + Filen kunne ikke findes. + + + The file is not readable. + Filen kan ikke læses. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor ({{ size }} {{ suffix }}). Tilladte maksimale størrelse {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mimetypen af filen er ugyldig ({{ type }}). Tilladte mimetyper er {{ types }}. + + + This value should be {{ limit }} or less. + Værdien skal være {{ limit }} eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Værdien er for lang. Den skal have {{ limit }} bogstaver eller mindre. + + + This value should be {{ limit }} or more. + Værdien skal være {{ limit }} eller mere. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Værdien er for kort. Den skal have {{ limit }} tegn eller flere. + + + This value should not be blank. + Værdien må ikke være blank. + + + This value should not be null. + Værdien må ikke være tom (null). + + + This value should be null. + Værdien skal være tom (null). + + + This value is not valid. + Værdien er ikke gyldig. + + + This value is not a valid time. + Værdien er ikke en gyldig tid. + + + This value is not a valid URL. + Værdien er ikke en gyldig URL. + + + The two values should be equal. + De to værdier skal være ens. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor. Den maksimale størrelse er {{ limit }} {{ suffix }}. + + + The file is too large. + Filen er for stor. + + + The file could not be uploaded. + Filen kunne ikke blive uploadet. + + + This value should be a valid number. + Værdien skal være et gyldigt tal. + + + This file is not a valid image. + Filen er ikke gyldigt billede. + + + This is not a valid IP address. + Dette er ikke en gyldig IP adresse. + + + This value is not a valid language. + Værdien er ikke et gyldigt sprog. + + + This value is not a valid locale. + Værdien er ikke en gyldig lokalitet. + + + This value is not a valid country. + Værdien er ikke et gyldigt land. + + + This value is already used. + Værdien er allerede i brug. + + + The size of the image could not be detected. + Størrelsen på billedet kunne ikke detekteres. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Billedbredden er for stor ({{ width }}px). Tilladt maksimumsbredde er {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Billedebredden er for lille ({{ width }}px). Forventet minimumshøjde er {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Billedhøjden er for stor ({{ height }}px). Tilladt maksimumshøjde er {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Billedhøjden er for lille ({{ height }}px). Forventet minimumshøjde er {{ min_height }}px. + + + This value should be the user's current password. + Værdien skal være brugerens nuværende password. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Værdien skal have præcis {{ limit }} tegn. + + + The file was only partially uploaded. + Filen var kun delvis uploadet. + + + No file was uploaded. + Ingen fil blev uploadet. + + + No temporary folder was configured in php.ini. + Ingen midlertidig mappe er konfigureret i php.ini. + + + Cannot write temporary file to disk. + Kan ikke skrive midlertidig fil til disk. + + + A PHP extension caused the upload to fail. + En PHP udvidelse forårsagede fejl i upload. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Denne samling skal indeholde {{ limit }} element eller flere.|Denne samling skal indeholde {{ limit }} elementer eller flere. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Denne samling skal indeholde {{ limit }} element eller mindre.|Denne samling skal indeholde {{ limit }} elementer eller mindre. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Denne samling skal indeholde præcis {{ limit }} element.|Denne samling skal indeholde præcis {{ limit }} elementer. + + + Invalid card number. + Ugyldigt kortnummer. + + + Unsupported card type or invalid card number. + Ikke-understøttet korttype eller ugyldigt kortnummer. + + + This is not a valid International Bank Account Number (IBAN). + Det er ikke en gyldig International Bank Account Number (IBAN). + + + This value is not a valid ISBN-10. + Værdien er ikke en gyldig ISBN-10. + + + This value is not a valid ISBN-13. + Værdien er ikke en gyldig ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Værdien er hverken en gyldig ISBN-10 eller en gyldig ISBN-13. + + + This value is not a valid ISSN. + Værdien er ikke en gyldig ISSN. + + + + 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 @@ + + + + + + This value should be false. + Dieser Wert sollte false sein. + + + This value should be true. + Dieser Wert sollte true sein. + + + This value should be of type {{ type }}. + Dieser Wert sollte vom Typ {{ type }} sein. + + + This value should be blank. + Dieser Wert sollte leer sein. + + + The value you selected is not a valid choice. + Sie haben einen ungültigen Wert ausgewählt. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Sie müssen mindestens {{ limit }} Möglichkeit wählen.|Sie müssen mindestens {{ limit }} Möglichkeiten wählen. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Sie dürfen höchstens {{ limit }} Möglichkeit wählen.|Sie dürfen höchstens {{ limit }} Möglichkeiten wählen. + + + One or more of the given values is invalid. + Einer oder mehrere der angegebenen Werte sind ungültig. + + + This field was not expected. + Dieses Feld wurde nicht erwartet. + + + This field is missing. + Dieses Feld fehlt. + + + This value is not a valid date. + Dieser Wert entspricht keiner gültigen Datumsangabe. + + + This value is not a valid datetime. + Dieser Wert entspricht keiner gültigen Datums- und Zeitangabe. + + + This value is not a valid email address. + Dieser Wert ist keine gültige E-Mail-Adresse. + + + The file could not be found. + Die Datei wurde nicht gefunden. + + + The file is not readable. + Die Datei ist nicht lesbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Die Datei ist zu groß ({{ size }} {{ suffix }}). Die maximal zulässige Größe beträgt {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Der Dateityp ist ungültig ({{ type }}). Erlaubte Dateitypen sind {{ types }}. + + + This value should be {{ limit }} or less. + Dieser Wert sollte kleiner oder gleich {{ limit }} sein. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Diese Zeichenkette ist zu lang. Sie sollte höchstens {{ limit }} Zeichen haben.|Diese Zeichenkette ist zu lang. Sie sollte höchstens {{ limit }} Zeichen haben. + + + This value should be {{ limit }} or more. + Dieser Wert sollte größer oder gleich {{ limit }} sein. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Diese Zeichenkette ist zu kurz. Sie sollte mindestens {{ limit }} Zeichen haben.|Diese Zeichenkette ist zu kurz. Sie sollte mindestens {{ limit }} Zeichen haben. + + + This value should not be blank. + Dieser Wert sollte nicht leer sein. + + + This value should not be null. + Dieser Wert sollte nicht null sein. + + + This value should be null. + Dieser Wert sollte null sein. + + + This value is not valid. + Dieser Wert ist nicht gültig. + + + This value is not a valid time. + Dieser Wert entspricht keiner gültigen Zeitangabe. + + + This value is not a valid URL. + Dieser Wert ist keine gültige URL. + + + The two values should be equal. + Die beiden Werte sollten identisch sein. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Die Datei ist zu groß. Die maximal zulässige Größe beträgt {{ limit }} {{ suffix }}. + + + The file is too large. + Die Datei ist zu groß. + + + The file could not be uploaded. + Die Datei konnte nicht hochgeladen werden. + + + This value should be a valid number. + Dieser Wert sollte eine gültige Zahl sein. + + + This file is not a valid image. + Diese Datei ist kein gültiges Bild. + + + This is not a valid IP address. + Dies ist keine gültige IP-Adresse. + + + This value is not a valid language. + Dieser Wert entspricht keiner gültigen Sprache. + + + This value is not a valid locale. + Dieser Wert entspricht keinem gültigen Gebietsschema. + + + This value is not a valid country. + Dieser Wert entspricht keinem gültigen Land. + + + This value is already used. + Dieser Wert wird bereits verwendet. + + + The size of the image could not be detected. + Die Größe des Bildes konnte nicht ermittelt werden. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Die Bildbreite ist zu groß ({{ width }}px). Die maximal zulässige Breite beträgt {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Die Bildbreite ist zu gering ({{ width }}px). Die erwartete Mindestbreite beträgt {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Die Bildhöhe ist zu groß ({{ height }}px). Die maximal zulässige Höhe beträgt {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Die Bildhöhe ist zu gering ({{ height }}px). Die erwartete Mindesthöhe beträgt {{ min_height }}px. + + + This value should be the user's current password. + Dieser Wert sollte dem aktuellen Benutzerpasswort entsprechen. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Dieser Wert sollte genau {{ limit }} Zeichen lang sein.|Dieser Wert sollte genau {{ limit }} Zeichen lang sein. + + + The file was only partially uploaded. + Die Datei wurde nur teilweise hochgeladen. + + + No file was uploaded. + Es wurde keine Datei hochgeladen. + + + No temporary folder was configured in php.ini. + Es wurde kein temporärer Ordner in der php.ini konfiguriert. + + + Cannot write temporary file to disk. + Kann die temporäre Datei nicht speichern. + + + A PHP extension caused the upload to fail. + Eine PHP-Erweiterung verhinderte den Upload. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Diese Sammlung sollte {{ limit }} oder mehr Elemente beinhalten.|Diese Sammlung sollte {{ limit }} oder mehr Elemente beinhalten. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Diese Sammlung sollte {{ limit }} oder weniger Elemente beinhalten.|Diese Sammlung sollte {{ limit }} oder weniger Elemente beinhalten. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Diese Sammlung sollte genau {{ limit }} Element beinhalten.|Diese Sammlung sollte genau {{ limit }} Elemente beinhalten. + + + Invalid card number. + Ungültige Kartennummer. + + + Unsupported card type or invalid card number. + Nicht unterstützer Kartentyp oder ungültige Kartennummer. + + + This is not a valid International Bank Account Number (IBAN). + Dieser Wert ist keine gültige IBAN-Kontonummer. + + + This value is not a valid ISBN-10. + Dieser Wert entspricht keiner gültigen ISBN-10. + + + This value is not a valid ISBN-13. + Dieser Wert entspricht keiner gültigen ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Dieser Wert ist weder eine gültige ISBN-10 noch eine gültige ISBN-13. + + + This value is not a valid ISSN. + Dieser Wert ist keine gültige ISSN. + + + This value is not a valid currency. + Dieser Wert ist keine gültige Währung. + + + This value should be equal to {{ compared_value }}. + Dieser Wert sollte gleich {{ compared_value }} sein. + + + This value should be greater than {{ compared_value }}. + Dieser Wert sollte größer als {{ compared_value }} sein. + + + This value should be greater than or equal to {{ compared_value }}. + Dieser Wert sollte größer oder gleich {{ compared_value }} sein. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Dieser Wert sollte identisch sein mit {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Dieser Wert sollte kleiner als {{ compared_value }} sein. + + + This value should be less than or equal to {{ compared_value }}. + Dieser Wert sollte kleiner oder gleich {{ compared_value }} sein. + + + This value should not be equal to {{ compared_value }}. + Dieser Wert sollte nicht {{ compared_value }} sein. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Dieser Wert sollte nicht identisch sein mit {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Das Seitenverhältnis des Bildes ist zu groß ({{ ratio }}). Der erlaubte Maximalwert ist {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Das Seitenverhältnis des Bildes ist zu klein ({{ ratio }}). Der erwartete Minimalwert ist {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Das Bild ist quadratisch ({{ width }}x{{ height }}px). Quadratische Bilder sind nicht erlaubt. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Das Bild ist im Querformat ({{ width }}x{{ height }}px). Bilder im Querformat sind nicht erlaubt. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Das Bild ist im Hochformat ({{ width }}x{{ height }}px). Bilder im Hochformat sind nicht erlaubt. + + + An empty file is not allowed. + Eine leere Datei ist nicht erlaubt. + + + This value does not match the expected {{ charset }} charset. + Dieser Wert entspricht nicht dem erwarteten Zeichensatz {{ charset }}. + + + + 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 @@ + + + + + + This value should be false. + Αυτή η τιμή πρέπει να είναι ψευδής. + + + This value should be true. + Αυτή η τιμή πρέπει να είναι αληθής. + + + This value should be of type {{ type }}. + Αυτή η τιμή πρέπει να είναι τύπου {{ type }}. + + + This value should be blank. + Αυτή η τιμή πρέπει να είναι κενή. + + + The value you selected is not a valid choice. + Η τιμή που επιλέχθηκε δεν αντιστοιχεί σε έγκυρη επιλογή. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Πρέπει να επιλέξετε τουλάχιστον {{ limit }} επιλογή.|Πρέπει να επιλέξετε τουλάχιστον {{ limit }} επιλογές. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Πρέπει να επιλέξετε το πολύ {{ limit }} επιλογή.|Πρέπει να επιλέξετε το πολύ {{ limit }} επιλογές. + + + One or more of the given values is invalid. + Μια ή περισσότερες τιμές δεν είναι έγκυρες. + + + This field was not expected. + Αυτό το πεδίο δεν ήταν αναμενόμενο. + + + This field is missing. + Λείπει αυτό το πεδίο. + + + This value is not a valid date. + Η τιμή δεν αντιστοιχεί σε έγκυρη ημερομηνία. + + + This value is not a valid datetime. + Η τιμή δεν αντιστοιχεί σε έγκυρη ημερομηνία και ώρα. + + + This value is not a valid email address. + Η τιμή δεν αντιστοιχεί σε έγκυρο email. + + + The file could not be found. + Το αρχείο δε μπορεί να βρεθεί. + + + The file is not readable. + Το αρχείο δεν είναι αναγνώσιμο. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Το αρχείο είναι πολύ μεγάλο ({{ size }} {{ suffix }}). Το μέγιστο επιτρεπτό μέγεθος είναι {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Ο τύπος mime του αρχείου δεν είναι έγκυρος ({{ type }}). Οι έγκρυοι τύποι mime είναι {{ types }}. + + + This value should be {{ limit }} or less. + Αυτή η τιμή θα έπρεπε να είναι {{ limit }} ή λιγότερο. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Αυτή η τιμή είναι πολύ μεγάλη. Θα έπρεπε να έχει {{ limit }} χαρακτήρα ή λιγότερο.|Αυτή η τιμή είναι πολύ μεγάλη. Θα έπρεπε να έχει {{ limit }} χαρακτήρες ή λιγότερο. + + + This value should be {{ limit }} or more. + Αυτή η τιμή θα έπρεπε να είναι {{ limit }} ή περισσότερο. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Αυτή η τιμή είναι πολύ μικρή. Θα έπρεπε να έχει {{ limit }} χαρακτήρα ή περισσότερο.|Αυτή η τιμή είναι πολύ μικρή. Θα έπρεπε να έχει {{ limit }} χαρακτήρες ή περισσότερο. + + + This value should not be blank. + Αυτή η τιμή δεν πρέπει να είναι κενή. + + + This value should not be null. + Αυτή η τιμή δεν πρέπει να είναι μηδενική. + + + This value should be null. + Αυτή η τιμή πρέπει να είναι μηδενική. + + + This value is not valid. + Αυτή η τιμή δεν είναι έκγυρη. + + + This value is not a valid time. + Αυτή η τιμή δεν αντιστοιχεί σε έγκυρη ώρα. + + + This value is not a valid URL. + Αυτή η τιμή δεν αντιστοιχεί σε έγκυρο URL. + + + The two values should be equal. + Οι δύο τιμές θα πρέπει να είναι ίδιες. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Το αρχείο είναι πολύ μεγάλο. Το μέγιστο επιτρεπτό μέγεθος είναι {{ limit }} {{ suffix }}. + + + The file is too large. + Το αρχείο είναι πολύ μεγάλο. + + + The file could not be uploaded. + Το αρχείο δε μπορεί να ανέβει. + + + This value should be a valid number. + Αυτή η τιμή θα πρέπει να είναι ένας έγκυρος αριθμός. + + + This file is not a valid image. + Το αρχείο δεν αποτελεί έγκυρη εικόνα. + + + This is not a valid IP address. + Αυτό δεν είναι μια έκγυρη διεύθυνση IP. + + + This value is not a valid language. + Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη γλώσσα. + + + This value is not a valid locale. + Αυτή η τιμή δεν αντιστοιχεί σε έκγυρο κωδικό τοποθεσίας. + + + This value is not a valid country. + Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη χώρα. + + + This value is already used. + Αυτή η τιμή χρησιμοποιείται ήδη. + + + The size of the image could not be detected. + Το μέγεθος της εικόνας δεν ήταν δυνατό να ανιχνευθεί. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Το πλάτος της εικόνας είναι πολύ μεγάλο ({{ width }}px). Το μέγιστο επιτρεπτό πλάτος είναι {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Το πλάτος της εικόνας είναι πολύ μικρό ({{ width }}px). Το ελάχιστο επιτρεπτό πλάτος είναι {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Το ύψος της εικόνας είναι πολύ μεγάλο ({{ height }}px). Το μέγιστο επιτρεπτό ύψος είναι {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Το ύψος της εικόνας είναι πολύ μικρό ({{ height }}px). Το ελάχιστο επιτρεπτό ύψος είναι {{ min_height }}px. + + + This value should be the user's current password. + Αυτή η τιμή θα έπρεπε να είναι ο τρέχων κωδικός. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Αυτή η τιμή θα έπρεπε να έχει ακριβώς {{ limit }} χαρακτήρα.|Αυτή η τιμή θα έπρεπε να έχει ακριβώς {{ limit }} χαρακτήρες. + + + The file was only partially uploaded. + Το αρχείο δεν ανέβηκε ολόκληρο. + + + No file was uploaded. + Δεν ανέβηκε κανένα αρχείο. + + + No temporary folder was configured in php.ini. + Κανένας προσωρινός φάκελος δεν έχει ρυθμιστεί στο php.ini. + + + Cannot write temporary file to disk. + Αδυναμία εγγραφής προσωρινού αρχείου στο δίσκο. + + + A PHP extension caused the upload to fail. + Μια επέκταση PHP προκάλεσε αδυναμία ανεβάσματος. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχείο ή περισσότερα.|Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχεία ή περισσότερα. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχείo ή λιγότερα.|Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχεία ή λιγότερα. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Αυτή η συλλογή θα πρέπει να περιέχει ακριβώς {{ limit }} στοιχείo.|Αυτή η συλλογή θα πρέπει να περιέχει ακριβώς {{ limit }} στοιχεία. + + + Invalid card number. + Μη έγκυρος αριθμός κάρτας. + + + Unsupported card type or invalid card number. + Μη υποστηριζόμενος τύπος κάρτας ή μη έγκυρος αριθμός κάρτας. + + + This is not a valid International Bank Account Number (IBAN). + Αυτό δεν αντιστοιχεί σε έκγυρο διεθνή αριθμό τραπεζικού λογαριασμού (IBAN). + + + This value is not a valid ISBN-10. + Αυτό δεν είναι έγκυρος κωδικός ISBN-10. + + + This value is not a valid ISBN-13. + Αυτό δεν είναι έγκυρος κωδικός ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Αυτό δεν είναι ούτε έγκυρος κωδικός ISBN-10 ούτε έγκυρος κωδικός ISBN-13. + + + This value is not a valid ISSN. + Αυτό δεν είναι έγκυρος κωδικός ISSN. + + + This value is not a valid currency. + Αυτό δεν αντιστοιχεί σε έγκυρο νόμισμα. + + + This value should be equal to {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι ίση με {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μεγαλύτερη από {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μεγαλύτερη ή ίση με {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι πανομοιότυπη με {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μικρότερη από {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μικρότερη ή ίση με {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Αυτή η τιμή δεν θα πρέπει να είναι ίση με {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Αυτή η τιμή δεν πρέπει να είναι πανομοιότυπη με {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + This value should be false. + + + This value should be true. + This value should be true. + + + This value should be of type {{ type }}. + This value should be of type {{ type }}. + + + This value should be blank. + This value should be blank. + + + The value you selected is not a valid choice. + The value you selected is not a valid choice. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + + + One or more of the given values is invalid. + One or more of the given values is invalid. + + + This field was not expected. + This field was not expected. + + + This field is missing. + This field is missing. + + + This value is not a valid date. + This value is not a valid date. + + + This value is not a valid datetime. + This value is not a valid datetime. + + + This value is not a valid email address. + This value is not a valid email address. + + + The file could not be found. + The file could not be found. + + + The file is not readable. + The file is not readable. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + + + This value should be {{ limit }} or less. + This value should be {{ limit }} or less. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + + + This value should be {{ limit }} or more. + This value should be {{ limit }} or more. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + + + This value should not be blank. + This value should not be blank. + + + This value should not be null. + This value should not be null. + + + This value should be null. + This value should be null. + + + This value is not valid. + This value is not valid. + + + This value is not a valid time. + This value is not a valid time. + + + This value is not a valid URL. + This value is not a valid URL. + + + The two values should be equal. + The two values should be equal. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + + + The file is too large. + The file is too large. + + + The file could not be uploaded. + The file could not be uploaded. + + + This value should be a valid number. + This value should be a valid number. + + + This file is not a valid image. + This file is not a valid image. + + + This is not a valid IP address. + This is not a valid IP address. + + + This value is not a valid language. + This value is not a valid language. + + + This value is not a valid locale. + This value is not a valid locale. + + + This value is not a valid country. + This value is not a valid country. + + + This value is already used. + This value is already used. + + + The size of the image could not be detected. + The size of the image could not be detected. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + + + This value should be the user's current password. + This value should be the user's current password. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + + + The file was only partially uploaded. + The file was only partially uploaded. + + + No file was uploaded. + No file was uploaded. + + + No temporary folder was configured in php.ini. + No temporary folder was configured in php.ini. + + + Cannot write temporary file to disk. + Cannot write temporary file to disk. + + + A PHP extension caused the upload to fail. + A PHP extension caused the upload to fail. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + + + Invalid card number. + Invalid card number. + + + Unsupported card type or invalid card number. + Unsupported card type or invalid card number. + + + This is not a valid International Bank Account Number (IBAN). + This is not a valid International Bank Account Number (IBAN). + + + This value is not a valid ISBN-10. + This value is not a valid ISBN-10. + + + This value is not a valid ISBN-13. + This value is not a valid ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + This value is neither a valid ISBN-10 nor a valid ISBN-13. + + + This value is not a valid ISSN. + This value is not a valid ISSN. + + + This value is not a valid currency. + This value is not a valid currency. + + + This value should be equal to {{ compared_value }}. + This value should be equal to {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + This value should be greater than {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + This value should be greater than or equal to {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + This value should be less than {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + This value should be less than or equal to {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + This value should not be equal to {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + + + An empty file is not allowed. + An empty file is not allowed. + + + This value does not match the expected {{ charset }} charset. + This value does not match the expected {{ charset }} charset. + + + + 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 @@ + + + + + + This value should be false. + Este valor debería ser falso. + + + This value should be true. + Este valor debería ser verdadero. + + + This value should be of type {{ type }}. + Este valor debería ser de tipo {{ type }}. + + + This value should be blank. + Este valor debería estar vacío. + + + The value you selected is not a valid choice. + El valor seleccionado no es una opción válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Debe seleccionar al menos {{ limit }} opción.|Debe seleccionar al menos {{ limit }} opciones. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Debe seleccionar como máximo {{ limit }} opción.|Debe seleccionar como máximo {{ limit }} opciones. + + + One or more of the given values is invalid. + Uno o más de los valores indicados no son válidos. + + + This field was not expected. + Este campo no se esperaba. + + + This field is missing. + Este campo está desaparecido. + + + This value is not a valid date. + Este valor no es una fecha válida. + + + This value is not a valid datetime. + Este valor no es una fecha y hora válidas. + + + This value is not a valid email address. + Este valor no es una dirección de email válida. + + + The file could not be found. + No se pudo encontrar el archivo. + + + The file is not readable. + No se puede leer el archivo. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + El archivo es demasiado grande ({{ size }} {{ suffix }}). El tamaño máximo permitido es {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + El tipo mime del archivo no es válido ({{ type }}). Los tipos mime válidos son {{ types }}. + + + This value should be {{ limit }} or less. + Este valor debería ser {{ limit }} o menos. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Este valor es demasiado largo. Debería tener {{ limit }} carácter o menos.|Este valor es demasiado largo. Debería tener {{ limit }} caracteres o menos. + + + This value should be {{ limit }} or more. + Este valor debería ser {{ limit }} o más. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Este valor es demasiado corto. Debería tener {{ limit }} carácter o más.|Este valor es demasiado corto. Debería tener {{ limit }} caracteres o más. + + + This value should not be blank. + Este valor no debería estar vacío. + + + This value should not be null. + Este valor no debería ser nulo. + + + This value should be null. + Este valor debería ser nulo. + + + This value is not valid. + Este valor no es válido. + + + This value is not a valid time. + Este valor no es una hora válida. + + + This value is not a valid URL. + Este valor no es una URL válida. + + + The two values should be equal. + Los dos valores deberían ser iguales. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + El archivo es demasiado grande. El tamaño máximo permitido es {{ limit }} {{ suffix }}. + + + The file is too large. + El archivo es demasiado grande. + + + The file could not be uploaded. + No se pudo subir el archivo. + + + This value should be a valid number. + Este valor debería ser un número válido. + + + This file is not a valid image. + El archivo no es una imagen válida. + + + This is not a valid IP address. + Esto no es una dirección IP válida. + + + This value is not a valid language. + Este valor no es un idioma válido. + + + This value is not a valid locale. + Este valor no es una localización válida. + + + This value is not a valid country. + Este valor no es un país válido. + + + This value is already used. + Este valor ya se ha utilizado. + + + The size of the image could not be detected. + No se pudo determinar el tamaño de la imagen. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + El ancho de la imagen es demasiado grande ({{ width }}px). El ancho máximo permitido es de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + El ancho de la imagen es demasiado pequeño ({{ width }}px). El ancho mínimo requerido es {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + La altura de la imagen es demasiado grande ({{ height }}px). La altura máxima permitida es de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + La altura de la imagen es demasiado pequeña ({{ height }}px). La altura mínima requerida es de {{ min_height }}px. + + + This value should be the user's current password. + Este valor debería ser la contraseña actual del usuario. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor debería tener exactamente {{ limit }} carácter.|Este valor debería tener exactamente {{ limit }} caracteres. + + + The file was only partially uploaded. + El archivo fue sólo subido parcialmente. + + + No file was uploaded. + Ningún archivo fue subido. + + + No temporary folder was configured in php.ini. + Ninguna carpeta temporal fue configurada en php.ini. + + + Cannot write temporary file to disk. + No se pudo escribir el archivo temporal en el disco. + + + A PHP extension caused the upload to fail. + Una extensión de PHP hizo que la subida fallara. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta colección debe contener {{ limit }} elemento o más.|Esta colección debe contener {{ limit }} elementos o más. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta colección debe contener {{ limit }} elemento o menos.|Esta colección debe contener {{ limit }} elementos o menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta colección debe contener exactamente {{ limit }} elemento.|Esta colección debe contener exactamente {{ limit }} elementos. + + + Invalid card number. + Número de tarjeta inválido. + + + Unsupported card type or invalid card number. + Tipo de tarjeta no soportado o número de tarjeta inválido. + + + This is not a valid International Bank Account Number (IBAN). + Esto no es un International Bank Account Number (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor no es un ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor no es un ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor no es ni un ISBN-10 válido ni un ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor no es un ISSN válido. + + + This value is not a valid currency. + Este valor no es una divisa válida. + + + This value should be equal to {{ compared_value }}. + Este valor debería ser igual que {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor debería ser mayor que {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor debería ser mayor o igual que {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor debería ser idéntico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor debería ser menor que {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor debería ser menor o igual que {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor debería ser distinto de {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor no debería ser idéntico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + La proporción de la imagen es demasiado grande ({{ ratio }}). La máxima proporción permitida es {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + La proporción de la imagen es demasiado pequeña ({{ ratio }}). La mínima proporción permitida es {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + La imagen es cuadrada ({{ width }}x{{ height }}px). Las imágenes cuadradas no están permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + La imagen está orientada horizontalmente ({{ width }}x{{ height }}px). Las imágenes orientadas horizontalmente no están permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + La imagen está orientada verticalmente ({{ width }}x{{ height }}px). Las imágenes orientadas verticalmente no están permitidas. + + + An empty file is not allowed. + No está permitido un archivo vacío. + + + This value does not match the expected {{ charset }} charset. + La codificación de caracteres para este valor debería ser {{ charset }}. + + + + 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 @@ + + + + + + This value should be false. + Väärtus peaks olema väär. + + + This value should be true. + Väärtus peaks oleme tõene. + + + This value should be of type {{ type }}. + Väärtus peaks olema {{ type }}-tüüpi. + + + This value should be blank. + Väärtus peaks olema tühi. + + + The value you selected is not a valid choice. + Väärtus peaks olema üks etteantud valikutest. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Valima peaks vähemalt {{ limit }} valikut. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Valima peaks mitte rohkem kui {{ limit }} valikut. + + + One or more of the given values is invalid. + One or more of the given values is invalid. + + + This field was not expected. + See väli ei oodatud. + + + This field is missing. + See väli on puudu. + + + This value is not a valid date. + Väärtus pole korrektne kuupäev. + + + This value is not a valid datetime. + Väärtus pole korrektne kuupäev ja kellaeg. + + + This value is not a valid email address. + Väärtus pole korrektne e-maili aadress. + + + The file could not be found. + Faili ei leita. + + + The file is not readable. + Fail ei ole loetav. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fail on liiga suur ({{ size }} {{ suffix }}). Suurim lubatud suurus on {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Faili sisutüüp on vigane ({{ type }}). Lubatud sisutüübid on {{ types }}. + + + This value should be {{ limit }} or less. + Väärtus peaks olema {{ limit }} või vähem. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Väärtus on liiga pikk. Pikkus peaks olema {{ limit }} tähemärki või vähem. + + + This value should be {{ limit }} or more. + Väärtus peaks olema {{ limit }} või rohkem. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Väärtus on liiga lühike. Pikkus peaks olema {{ limit }} tähemärki või rohkem. + + + This value should not be blank. + Väärtus ei tohiks olla tühi. + + + This value should not be null. + Väärtus ei tohiks olla 'null'. + + + This value should be null. + Väärtus peaks olema 'null'. + + + This value is not valid. + Väärtus on vigane. + + + This value is not a valid time. + Väärtus pole korrektne aeg. + + + This value is not a valid URL. + Väärtus pole korrektne URL. + + + The two values should be equal. + Väärtused peaksid olema võrdsed. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fail on liiga suur. Maksimaalne lubatud suurus on {{ limit }} {{ suffix }}. + + + The file is too large. + Fail on liiga suur. + + + The file could not be uploaded. + Faili ei saa üles laadida. + + + This value should be a valid number. + Väärtus peaks olema korrektne number. + + + This file is not a valid image. + Fail ei ole korrektne pilt. + + + This is not a valid IP address. + IP aadress pole korrektne. + + + This value is not a valid language. + Väärtus pole korrektne keel. + + + This value is not a valid locale. + Väärtus pole korrektne asukohakeel. + + + This value is not a valid country. + Väärtus pole olemasolev riik. + + + This value is already used. + Väärtust on juba kasutatud. + + + The size of the image could not be detected. + Pildi suurust polnud võimalik tuvastada. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Pilt on liiga lai ({{ width }}px). Suurim lubatud laius on {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Pilt on liiga kitsas ({{ width }}px). Vähim lubatud laius on {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Pilt on liiga pikk ({{ height }}px). Lubatud suurim pikkus on {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Pilt pole piisavalt pikk ({{ height }}px). Lubatud vähim pikkus on {{ min_height }}px. + + + This value should be the user's current password. + Väärtus peaks olema kasutaja kehtiv salasõna. + + + This value should have exactly {{ limit }} characters. + Väärtus peaks olema täpselt {{ limit }} tähemärk pikk.|Väärtus peaks olema täpselt {{ limit }} tähemärki pikk. + + + The file was only partially uploaded. + Fail ei laetud täielikult üles. + + + No file was uploaded. + Ühtegi faili ei laetud üles. + + + No temporary folder was configured in php.ini. + Ühtegi ajutist kausta polnud php.ini-s seadistatud. + + + Cannot write temporary file to disk. + Ajutist faili ei saa kettale kirjutada. + + + A PHP extension caused the upload to fail. + PHP laiendi tõttu ebaõnnestus faili üleslaadimine. + + + This collection should contain {{ limit }} elements or more. + Kogumikus peaks olema vähemalt {{ limit }} element.|Kogumikus peaks olema vähemalt {{ limit }} elementi. + + + This collection should contain {{ limit }} elements or less. + Kogumikus peaks olema ülimalt {{ limit }} element.|Kogumikus peaks olema ülimalt {{ limit }} elementi. + + + This collection should contain exactly {{ limit }} elements. + Kogumikus peaks olema täpselt {{ limit }} element.|Kogumikus peaks olema täpselt {{ limit }}|elementi. + + + Invalid card number. + Vigane kaardi number. + + + Unsupported card type or invalid card number. + Kaardi tüüpi ei toetata või kaardi number on vigane. + + + This is not a valid International Bank Account Number (IBAN). + Väärtus pole korrektne IBAN-number. + + + This value is not a valid ISBN-10. + Väärtus pole korrektne ISBN-10. + + + This value is not a valid ISBN-13. + Väärtus pole korrektne ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Väärtus pole korrektne ISBN-10 ega ISBN-13. + + + This value is not a valid ISSN. + Väärtus pole korrektne ISSN. + + + This value is not a valid currency. + Väärtus pole korrektne valuuta. + + + This value should be equal to {{ compared_value }}. + Väärtus peaks olema võrdne {{ compared_value }}-ga. + + + This value should be greater than {{ compared_value }}. + Väärtus peaks olema suurem kui {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Väärtus peaks olema suurem kui või võrduma {{ compared_value }}-ga. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Väärtus peaks olema identne väärtusega {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Väärtus peaks olema väiksem kui {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Väärtus peaks olema väiksem kui või võrduma {{ compared_value }}-ga. + + + This value should not be equal to {{ compared_value }}. + Väärtus ei tohiks võrduda {{ compared_value }}-ga. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Väärtus ei tohiks olla identne väärtusega {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + Balio hau faltsua izan beharko litzateke. + + + This value should be true. + Balio hau egia izan beharko litzateke. + + + This value should be of type {{ type }}. + Balio hau {{ type }} motakoa izan beharko litzateke. + + + This value should be blank. + Balio hau hutsik egon beharko litzateke. + + + The value you selected is not a valid choice. + Hautatu duzun balioa ez da aukera egoki bat. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Gutxienez aukera {{ limit }} hautatu behar duzu.|Gutxienez {{ limit }} aukera hautatu behar dituzu. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Gehienez aukera {{ limit }} hautatu behar duzu.|Gehienez {{ limit }} aukera hautatu behar dituzu. + + + One or more of the given values is invalid. + Emandako balioetatik gutxienez bat ez da egokia. + + + This field was not expected. + Eremu hau ez zen espero. + + + This field is missing. + Eremu hau falta da. + + + This value is not a valid date. + Balio hau ez da data egoki bat. + + + This value is not a valid datetime. + Balio hau ez da data-ordu egoki bat. + + + This value is not a valid email address. + Balio hau ez da posta elektroniko egoki bat. + + + The file could not be found. + Ezin izan da fitxategia aurkitu. + + + The file is not readable. + Fitxategia ez da irakurgarria. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fitxategia handiegia da ({{ size }} {{ suffix }}). Baimendutako tamaina handiena {{ limit }} {{ suffix }} da. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Fitxategiaren mime mota ez da egokia ({{ type }}). Hauek dira baimendutako mime motak: {{ types }}. + + + This value should be {{ limit }} or less. + Balio hau gehienez {{ limit }} izan beharko litzateke. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Balio hau luzeegia da. Gehienez karaktere {{ limit }} eduki beharko luke.|Balio hau luzeegia da. Gehienez {{ limit }} karaktere eduki beharko lituzke. + + + This value should be {{ limit }} or more. + Balio hau gutxienez {{ limit }} izan beharko litzateke. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Balio hau motzegia da. Karaktere {{ limit }} gutxienez eduki beharko luke.|Balio hau motzegia da. Gutxienez {{ limit }} karaktere eduki beharko lituzke. + + + This value should not be blank. + Balio hau ez litzateke hutsik egon behar. + + + This value should not be null. + Balio hau ez litzateke nulua izan behar. + + + This value should be null. + Balio hau nulua izan beharko litzateke. + + + This value is not valid. + Balio hau ez da egokia. + + + This value is not a valid time. + Balio hau ez da ordu egoki bat. + + + This value is not a valid URL. + Balio hau ez da baliabideen kokatzaile uniforme (URL) egoki bat. + + + The two values should be equal. + Bi balioak berdinak izan beharko lirateke. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fitxategia handiegia da. Baimendutako tamaina handiena {{ limit }} {{ suffix }} da. + + + The file is too large. + Fitxategia handiegia da. + + + The file could not be uploaded. + Ezin izan da fitxategia igo. + + + This value should be a valid number. + Balio hau zenbaki egoki bat izan beharko litzateke. + + + This file is not a valid image. + Fitxategi hau ez da irudi egoki bat. + + + This is not a valid IP address. + Honako hau ez da IP helbide egoki bat. + + + This value is not a valid language. + Balio hau ez da hizkuntza egoki bat. + + + This value is not a valid locale. + Balio hau ez da kokapen egoki bat. + + + This value is not a valid country. + Balio hau ez da herrialde egoki bat. + + + This value is already used. + Balio hau jadanik erabilia izan da. + + + The size of the image could not be detected. + Ezin izan da irudiaren tamaina detektatu. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Irudiaren zabalera handiegia da ({{ width }}px). Onartutako gehienezko zabalera {{ max_width }}px dira. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Irudiaren zabalera txikiegia da ({{ width }}px). Onartutako gutxieneko zabalera {{ min_width }}px dira. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Irudiaren altuera handiegia da ({{ height }}px). Onartutako gehienezko altuera {{ max_height }}px dira. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Irudiaren altuera txikiegia da ({{ height }}px). Onartutako gutxieneko altuera {{ min_height }}px dira. + + + This value should be the user's current password. + Balio hau uneko erabiltzailearen pasahitza izan beharko litzateke. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Balio honek zehazki karaktere {{ limit }} izan beharko luke.|Balio honek zehazki {{ limit }} karaktere izan beharko lituzke. + + + The file was only partially uploaded. + Fitxategiaren zati bat bakarrik igo da. + + + No file was uploaded. + Ez da fitxategirik igo. + + + No temporary folder was configured in php.ini. + Ez da aldi baterako karpetarik konfiguratu php.ini fitxategian. + + + Cannot write temporary file to disk. + Ezin izan da aldi baterako fitxategia diskoan idatzi. + + + A PHP extension caused the upload to fail. + PHP luzapen batek igoeraren hutsa eragin du. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Bilduma honek gutxienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gutxienez {{ limit }} elementu eduki beharko lituzke. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Bilduma honek gehienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gehienez {{ limit }} elementu eduki beharko lituzke. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Bilduma honek zehazki elementu {{ limit }} eduki beharko luke.|Bilduma honek zehazki {{ limit }} elementu eduki beharko lituzke. + + + Invalid card number. + Txartel zenbaki baliogabea. + + + Unsupported card type or invalid card number. + Txartel mota onartezina edo txartel zenbaki baliogabea. + + + This is not a valid International Bank Account Number (IBAN). + Hau ez da baliozko banku internazionaleko kontu zenbaki (IBAN) bat. + + + This value is not a valid ISBN-10. + Balio hau ez da onartutako ISBN-10 bat. + + + This value is not a valid ISBN-13. + Balio hau ez da onartutako ISBN-13 bat. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Balio hau ez da onartutako ISBN-10 edo ISBN-13 bat. + + + This value is not a valid ISSN. + Balio hau ez da onartutako ISSN bat. + + + This value is not a valid currency. + Balio hau ez da baliozko moneta bat. + + + This value should be equal to {{ compared_value }}. + Balio hau {{ compared_value }}-(r)en berbera izan beharko litzateke. + + + This value should be greater than {{ compared_value }}. + Balio hau {{ compared_value }} baino handiagoa izan beharko litzateke. + + + This value should be greater than or equal to {{ compared_value }}. + Balio hau {{ compared_value }}-(r)en berdina edota handiagoa izan beharko litzateke. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Balio hau {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan beharko litzateke. + + + This value should be less than {{ compared_value }}. + Balio hau {{ compared_value }} baino txikiagoa izan beharko litzateke. + + + This value should be less than or equal to {{ compared_value }}. + Balio hau {{ compared_value }}-(r)en berdina edota txikiagoa izan beharko litzateke. + + + This value should not be equal to {{ compared_value }}. + Balio hau ez litzateke {{ compared_value }}-(r)en berdina izan behar. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Balio hau ez litzateke {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan behar. + + + + 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 @@ + + + + + + This value should be false. + این مقدار باید نادرست(False) باشد. + + + This value should be true. + این مقدار باید درست(True) باشد. + + + This value should be of type {{ type }}. + این مقدار باید از نوع {{ type }} باشد. + + + This value should be blank. + این فیلد باید خالی باشد. + + + The value you selected is not a valid choice. + گزینه انتخابی معتبر نیست. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + باید حداقل {{ limit }} گزینه انتخاب کنید.|باید حداقل {{ limit }} گزینه انتخاب کنید. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + حداکثر {{ limit }} گزینه می توانید انتخاب کنید.|حداکثر {{ limit }} گزینه می توانید انتخاب کنید. + + + One or more of the given values is invalid. + یک یا چند مقدار نامعتبر وجود دارد. + + + The fields {{ fields }} were not expected. + فیلدهای {{ fields }} اضافی هستند. + + + The fields {{ fields }} are missing. + فیلدهای {{ fields }} کم هستند. + + + This value is not a valid date. + این مقدار یک تاریخ معتبر نیست. + + + This value is not a valid datetime. + این مقدار یک تاریخ و زمان معتبر نیست. + + + This value is not a valid email address. + این یک رایانامه معتبر نیست. + + + The file could not be found. + فایل پیدا نشد. + + + The file is not readable. + فایل قابلیت خواندن ندارد. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + فایل بیش از اندازه بزرگ است({{ size }} {{ suffix }}). حداکثر اندازه مجاز برابر {{ limit }} {{ suffix }} است. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + این نوع فایل مجاز نیست({{ type }}). نوع های مجاز {{ types }} هستند. + + + This value should be {{ limit }} or less. + این مقدار باید کوچکتر یا مساوی {{ limit }} باشد. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + بسیار طولانی است.حداکثر تعداد حروف مجاز برابر {{ limit }} است.|بسیار طولانی است.حداکثر تعداد حروف مجاز برابر {{ limit }} است. + + + This value should be {{ limit }} or more. + این مقدار باید برابر و یا بیشتر از {{ limit }} باشد. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + بسیار کوتاه است.تعداد حروف باید حداقل {{ limit }} باشد.|بسیار کوتاه است.تعداد حروف باید حداقل {{ limit }} باشد. + + + This value should not be blank. + این مقدار نباید تهی باشد. + + + This value should not be null. + باید مقداری داشته باشد.. + + + This value should be null. + نباید مقداری داشته باشد. + + + This value is not valid. + این مقدار معتبر نیست. + + + This value is not a valid time. + این مقدار یک زمان صحیح نیست. + + + This value is not a valid URL. + این یک URL معتبر نیست. + + + The two values should be equal. + دو مقدار باید برابر باشند. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + فایل بیش از اندازه بزرگ است. حداکثر اندازه مجاز برابر {{ limit }} {{ suffix }} است. + + + The file is too large. + فایل بیش از اندازه بزرگ است. + + + The file could not be uploaded. + بارگذاری فایل با شکست مواجه شد. + + + This value should be a valid number. + این مقدار باید یک عدد معتبر باشد. + + + This file is not a valid image. + این فایل یک تصویر نیست. + + + This is not a valid IP address. + این مقدار یک IP معتبر نیست. + + + This value is not a valid language. + این مقدار یک زبان صحیح نیست. + + + This value is not a valid locale. + این مقدار یک محل صحیح نیست. + + + This value is not a valid country. + این مقدار یک کشور صحیح نیست. + + + This value is already used. + این مقدار قبلا مورد استفاده قرار گرفته است. + + + The size of the image could not be detected. + اندازه تصویر قابل شناسایی نیست. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + طول تصویر بسیار بزرگ است ({{ width }}px). بشینه طول مجاز {{ max_width }}px است. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + طول تصویر بسیار کوچک است ({{ width }}px). کمینه طول موردنظر {{ min_width }}px است. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ارتفاع تصویر بسیار بزرگ است ({{ height }}px). بشینه ارتفاع مجاز {{ max_height }}px است. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ارتفاع تصویر بسیار کوچک است ({{ height }}px). کمینه ارتفاع موردنظر {{ min_height }}px است. + + + This value should be the user's current password. + این مقدار می بایست کلمه عبور کنونی کاربر باشد. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + این مقدار می بایست دقیقا {{ limit }} کاراکتر داشته باشد.| این مقدار می بایست دقیقا {{ limit }} کاراکتر داشته باشد. + + + The file was only partially uploaded. + فایل به صورت جزیی بارگذاری شده است. + + + No file was uploaded. + هیچ فایلی بارگذاری نشد. + + + No temporary folder was configured in php.ini. + فولدر موقت در php.ini پیکربندی نشده است. + + + Cannot write temporary file to disk. + فایل موقت را نمی توان در دیسک نوشت. + + + A PHP extension caused the upload to fail. + اکستنشن PHP موجب شد که بارگذاری فایل با شکست مواجه شود. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + این مجموعه می بایست دارای {{ limit }} عنصر یا بیشتر باشد.|این مجموعه می بایست دارای {{ limit }} عنصر یا بیشتر باشد. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + این مجموعه می بایست دارای حداقل {{ limit }} عنصر یا کمتر باشد.|این مجموعه می بایست دارای {{ limit }} عنصر یا کمتر باشد. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + این مجموعه می بایست به طور دقیق دارا {{ limit }} عنصر باشد.|این مجموعه می بایست به طور دقیق دارای {{ limit }} قلم باشد. + + + Invalid card number. + شماره کارت نامعتبر است. + + + Unsupported card type or invalid card number. + نوع کارت پشتیبانی نمی شود یا شماره کارت نامعتبر است. + + + This is not a valid International Bank Account Number (IBAN). + این یک شماره حساب بین المللی بانک (IBAN) درست نیست. + + + This value is not a valid ISBN-10. + این مقدار یک ISBN-10 درست نیست. + + + This value is not a valid ISBN-13. + این مقدار یک ISBN-13 درست نیست. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + این مقدار یک ISBN-10 درست یا ISBN-13 درست نیست. + + + This value is not a valid ISSN. + این مقدار یک ISSN درست نیست. + + + This value is not a valid currency. + این مقدار یک یکای پول درست نیست. + + + This value should be equal to {{ compared_value }}. + این مقدار باید برابر با {{ compared_value }} باشد. + + + This value should be greater than {{ compared_value }}. + این مقدار باید از {{ compared_value }} بیشتر باشد. + + + This value should be greater than or equal to {{ compared_value }}. + این مقدار باید بزرگتر یا مساوی با {{ compared_value }} باشد. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + این مقدار باید با {{ compared_value_type }} {{ compared_value }} یکی باشد. + + + This value should be less than {{ compared_value }}. + این مقدار باید کمتر از {{ compared_value }} باشد. + + + This value should be less than or equal to {{ compared_value }}. + این مقدار باید کمتر یا مساوی با {{ compared_value }} باشد. + + + This value should not be equal to {{ compared_value }}. + این مقدار نباید با {{ compared_value }} برابر باشد. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + این مقدار نباید {{ compared_value_type }} {{ compared_value }} یکی باشد. + + + + 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 @@ + + + + + + This value should be false. + Arvon tulee olla epätosi. + + + This value should be true. + Arvon tulee olla tosi. + + + This value should be of type {{ type }}. + Arvon tulee olla tyyppiä {{ type }}. + + + This value should be blank. + Arvon tulee olla tyhjä. + + + The value you selected is not a valid choice. + Arvon tulee olla yksi annetuista vaihtoehdoista. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Sinun tulee valita vähintään {{ limit }} vaihtoehtoa. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Sinun tulee valitan enintään {{ limit }} vaihtoehtoa. + + + One or more of the given values is invalid. + Yksi tai useampi annetuista arvoista on virheellinen. + + + This field was not expected. + Tässä kentässä ei odotettu. + + + This field is missing. + Tämä kenttä puuttuu. + + + This value is not a valid date. + Annettu arvo ei ole kelvollinen päivämäärä. + + + This value is not a valid datetime. + Annettu arvo ei ole kelvollinen päivämäärä ja kellonaika. + + + This value is not a valid email address. + Annettu arvo ei ole kelvollinen sähköpostiosoite. + + + The file could not be found. + Tiedostoa ei löydy. + + + The file is not readable. + Tiedostoa ei voida lukea. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Tiedostonkoko ({{ size }} {{ suffix }}) on liian iso. Suurin sallittu tiedostonkoko on {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Tiedostotyyppi ({{ type }}) on virheellinen. Sallittuja tiedostotyyppejä ovat {{ types }}. + + + This value should be {{ limit }} or less. + Arvon tulee olla {{ limit }} tai vähemmän. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Liian pitkä syöte. Syöte saa olla enintään {{ limit }} merkkiä. + + + This value should be {{ limit }} or more. + Arvon tulee olla {{ limit }} tai enemmän. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Liian lyhyt syöte. Syötteen tulee olla vähintään {{ limit }} merkkiä. + + + This value should not be blank. + Kenttä ei voi olla tyhjä. + + + This value should not be null. + Syöte ei voi olla null. + + + This value should be null. + Syötteen tulee olla null. + + + This value is not valid. + Virheellinen arvo. + + + This value is not a valid time. + Annettu arvo ei ole kelvollinen kellonaika. + + + This value is not a valid URL. + Annettu arvo ei ole kelvollinen URL-osoite. + + + The two values should be equal. + Kahden annetun arvon tulee olla samat. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Annettu tiedosto on liian iso. Suurin sallittu tiedostokoko on {{ limit }} {{ suffix }}. + + + The file is too large. + Tiedosto on liian iso. + + + The file could not be uploaded. + Tiedoston siirto epäonnistui. + + + This value should be a valid number. + Tämän arvon tulee olla numero. + + + This file is not a valid image. + Tämä tiedosto ei ole kelvollinen kuva. + + + This is not a valid IP address. + Tämä ei ole kelvollinen IP-osoite. + + + This value is not a valid language. + Tämä arvo ei ole kelvollinen kieli. + + + This value is not a valid locale. + Tämä arvo ei ole kelvollinen kieli- ja alueasetus (locale). + + + This value is not a valid country. + Tämä arvo ei ole kelvollinen maa. + + + This value is already used. + Tämä arvo on jo käytetty. + + + The size of the image could not be detected. + Kuvan kokoa ei voitu tunnistaa. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Kuva on liian leveä ({{ width }}px). Sallittu maksimileveys on {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Kuva on liian kapea ({{ width }}px). Leveyden tulisi olla vähintään {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Kuva on liian korkea ({{ width }}px). Sallittu maksimikorkeus on {{ max_width }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Kuva on liian matala ({{ height }}px). Korkeuden tulisi olla vähintään {{ min_height }}px. + + + This value should be the user's current password. + Tämän arvon tulisi olla käyttäjän tämänhetkinen salasana. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Tämän arvon tulisi olla tasan yhden merkin pituinen.|Tämän arvon tulisi olla tasan {{ limit }} merkkiä pitkä. + + + The file was only partially uploaded. + Tiedosto ladattiin vain osittain. + + + No file was uploaded. + Tiedostoa ei ladattu. + + + No temporary folder was configured in php.ini. + Väliaikaishakemistoa ei ole asetettu php.ini -tiedostoon. + + + Cannot write temporary file to disk. + Väliaikaistiedostoa ei voitu kirjoittaa levylle. + + + A PHP extension caused the upload to fail. + PHP-laajennoksen vuoksi tiedoston lataus epäonnistui. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Tässä ryhmässä tulisi olla yksi tai useampi elementti.|Tässä ryhmässä tulisi olla vähintään {{ limit }} elementtiä. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Tässä ryhmässä tulisi olla enintään yksi elementti.|Tässä ryhmässä tulisi olla enintään {{ limit }} elementtiä. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Tässä ryhmässä tulisi olla tasan yksi elementti.|Tässä ryhmässä tulisi olla enintään {{ limit }} elementtiä. + + + Invalid card number. + Virheellinen korttinumero. + + + Unsupported card type or invalid card number. + Tätä korttityyppiä ei tueta tai korttinumero on virheellinen. + + + + 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 @@ + + + + + + This value should be false. + Cette valeur doit être fausse. + + + This value should be true. + Cette valeur doit être vraie. + + + This value should be of type {{ type }}. + Cette valeur doit être de type {{ type }}. + + + This value should be blank. + Cette valeur doit être vide. + + + The value you selected is not a valid choice. + Cette valeur doit être l'un des choix proposés. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Vous devez sélectionner au moins {{ limit }} choix.|Vous devez sélectionner au moins {{ limit }} choix. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Vous devez sélectionner au maximum {{ limit }} choix.|Vous devez sélectionner au maximum {{ limit }} choix. + + + One or more of the given values is invalid. + Une ou plusieurs des valeurs soumises sont invalides. + + + This field was not expected. + Ce champ n'a pas été prévu. + + + This field is missing. + Ce champ est manquant. + + + This value is not a valid date. + Cette valeur n'est pas une date valide. + + + This value is not a valid datetime. + Cette valeur n'est pas une date valide. + + + This value is not a valid email address. + Cette valeur n'est pas une adresse email valide. + + + The file could not be found. + Le fichier n'a pas été trouvé. + + + The file is not readable. + Le fichier n'est pas lisible. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Le fichier est trop volumineux ({{ size }} {{ suffix }}). Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Le type du fichier est invalide ({{ type }}). Les types autorisés sont {{ types }}. + + + This value should be {{ limit }} or less. + Cette valeur doit être inférieure ou égale à {{ limit }}. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Cette 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. + + + This value should be {{ limit }} or more. + Cette valeur doit être supérieure ou égale à {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Cette 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. + + + This value should not be blank. + Cette valeur ne doit pas être vide. + + + This value should not be null. + Cette valeur ne doit pas être nulle. + + + This value should be null. + Cette valeur doit être nulle. + + + This value is not valid. + Cette valeur n'est pas valide. + + + This value is not a valid time. + Cette valeur n'est pas une heure valide. + + + This value is not a valid URL. + Cette valeur n'est pas une URL valide. + + + The two values should be equal. + Les deux valeurs doivent être identiques. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Le fichier est trop volumineux. Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}. + + + The file is too large. + Le fichier est trop volumineux. + + + The file could not be uploaded. + Le téléchargement de ce fichier est impossible. + + + This value should be a valid number. + Cette valeur doit être un nombre. + + + This file is not a valid image. + Ce fichier n'est pas une image valide. + + + This is not a valid IP address. + Cette adresse IP n'est pas valide. + + + This value is not a valid language. + Cette langue n'est pas valide. + + + This value is not a valid locale. + Ce paramètre régional n'est pas valide. + + + This value is not a valid country. + Ce pays n'est pas valide. + + + This value is already used. + Cette valeur est déjà utilisée. + + + The size of the image could not be detected. + La taille de l'image n'a pas pu être détectée. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + La largeur de l'image est trop grande ({{ width }}px). La largeur maximale autorisée est de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + La largeur de l'image est trop petite ({{ width }}px). La largeur minimale attendue est de {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + La hauteur de l'image est trop grande ({{ height }}px). La hauteur maximale autorisée est de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + La hauteur de l'image est trop petite ({{ height }}px). La hauteur minimale attendue est de {{ min_height }}px. + + + This value should be the user's current password. + Cette valeur doit être le mot de passe actuel de l'utilisateur. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Cette chaine doit avoir exactement {{ limit }} caractère.|Cette chaine doit avoir exactement {{ limit }} caractères. + + + The file was only partially uploaded. + Le fichier a été partiellement transféré. + + + No file was uploaded. + Aucun fichier n'a été transféré. + + + No temporary folder was configured in php.ini. + Aucun répertoire temporaire n'a été configuré dans le php.ini. + + + Cannot write temporary file to disk. + Impossible d'écrire le fichier temporaire sur le disque. + + + A PHP extension caused the upload to fail. + Une extension PHP a empêché le transfert du fichier. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Cette collection doit contenir {{ limit }} élément ou plus.|Cette collection doit contenir {{ limit }} éléments ou plus. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Cette collection doit contenir {{ limit }} élément ou moins.|Cette collection doit contenir {{ limit }} éléments ou moins. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Cette collection doit contenir exactement {{ limit }} élément.|Cette collection doit contenir exactement {{ limit }} éléments. + + + Invalid card number. + Numéro de carte invalide. + + + Unsupported card type or invalid card number. + Type de carte non supporté ou numéro invalide. + + + This is not a valid International Bank Account Number (IBAN). + Le numéro IBAN (International Bank Account Number) saisi n'est pas valide. + + + This value is not a valid ISBN-10. + Cette valeur n'est pas un code ISBN-10 valide. + + + This value is not a valid ISBN-13. + Cette valeur n'est pas un code ISBN-13 valide. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Cette valeur n'est ni un code ISBN-10, ni un code ISBN-13 valide. + + + This value is not a valid ISSN. + Cette valeur n'est pas un code ISSN valide. + + + This value is not a valid currency. + Cette valeur n'est pas une devise valide. + + + This value should be equal to {{ compared_value }}. + Cette valeur doit être égale à {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Cette valeur doit être supérieure à {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Cette valeur doit être supérieure ou égale à {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Cette valeur doit être identique à {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Cette valeur doit être inférieure à {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Cette valeur doit être inférieure ou égale à {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Cette valeur ne doit pas être égale à {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Cette valeur ne doit pas être identique à {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Le rapport largeur/hauteur de l'image est trop grand ({{ ratio }}). Le rapport maximal autorisé est {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Le rapport largeur/hauteur de l'image est trop petit ({{ ratio }}). Le rapport minimal attendu est {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + L'image est carrée ({{ width }}x{{ height }}px). Les images carrées ne sont pas autorisées. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + L'image est au format paysage ({{ width }}x{{ height }}px). Les images au format paysage ne sont pas autorisées. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + L'image est au format portrait ({{ width }}x{{ height }}px). Les images au format portrait ne sont pas autorisées. + + + An empty file is not allowed. + Un fichier vide n'est pas autorisé. + + + This value does not match the expected {{ charset }} charset. + Cette valeur ne correspond pas au jeu de caractères {{ charset }} attendu. + + + + 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 @@ + + + + + + This value should be false. + Este valor debería ser falso. + + + This value should be true. + Este valor debería ser verdadeiro. + + + This value should be of type {{ type }}. + Este valor debería ser de tipo {{ type }}. + + + This value should be blank. + Este valor debería estar baleiro. + + + The value you selected is not a valid choice. + O valor seleccionado non é unha opción válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Debe seleccionar polo menos {{ limit }} opción.|Debe seleccionar polo menos {{ limit }} opcions. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Debe seleccionar como máximo {{ limit }} opción.|Debe seleccionar como máximo {{ limit }} opcions. + + + One or more of the given values is invalid. + Un ou máis dos valores indicados non son válidos. + + + This field was not expected. + Este campo non era esperado. + + + This field is missing. + Este campo falta. + + + This value is not a valid date. + Este valor non é unha data válida. + + + This value is not a valid datetime. + Este valor non é unha data e hora válidas. + + + This value is not a valid email address. + Este valor non é unha dirección de correo electrónico válida. + + + The file could not be found. + Non se puido atopar o arquivo. + + + The file is not readable. + O arquivo non se pode ler. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é demasiado grande ({{ size }} {{ suffix }}). O tamaño máximo permitido é {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + O tipo mime do arquivo non é válido ({{ type }}). Os tipos mime válidos son {{ types }}. + + + This value should be {{ limit }} or less. + Este valor debería ser {{ limit }} ou menos. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Este valor é demasiado longo. Debería ter {{ limit }} carácter ou menos.|Este valor é demasiado longo. Debería ter {{ limit }} caracteres ou menos. + + + This value should be {{ limit }} or more. + Este valor debería ser {{ limit }} ou máis. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Este valor é demasiado curto. Debería ter {{ limit }} carácter ou máis.|Este valor é demasiado corto. Debería ter {{ limit }} caracteres ou máis. + + + This value should not be blank. + Este valor non debería estar baleiro. + + + This value should not be null. + Este valor non debería ser null. + + + This value should be null. + Este valor debería ser null. + + + This value is not valid. + Este valor non é válido. + + + This value is not a valid time. + Este valor non é unha hora válida. + + + This value is not a valid URL. + Este valor non é unha URL válida. + + + The two values should be equal. + Os dous valores deberían ser iguais. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é demasiado grande. O tamaño máximo permitido é {{ limit }} {{ suffix }}. + + + The file is too large. + O arquivo é demasiado grande. + + + The file could not be uploaded. + No se puido cargar o arquivo. + + + This value should be a valid number. + Este valor debería ser un número válido. + + + This file is not a valid image. + O arquivo non é unha imaxe válida. + + + This is not a valid IP address. + Isto non é unha dirección IP válida. + + + This value is not a valid language. + Este valor non é un idioma válido. + + + This value is not a valid locale. + Este valor non é unha localización válida. + + + This value is not a valid country. + Este valor non é un país válido. + + + This value is already used. + Este valor xa está a ser empregado. + + + The size of the image could not be detected. + Non se puido determinar o tamaño da imaxe. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura da imaxe é demasiado grande ({{ width }}px). A largura máxima permitida son {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura da imaxe é demasiado pequena ({{ width }}px). A largura mínima requerida son {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura da imaxe é demasiado grande ({{ height }}px). A altura máxima permitida son {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura da imaxe é demasiado pequena ({{ height }}px). A altura mínima requerida son {{ min_height }}px. + + + This value should be the user's current password. + Este valor debería ser a contrasinal actual do usuario. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor debería ter exactamente {{ limit }} carácter.|Este valor debería ter exactamente {{ limit }} caracteres. + + + The file was only partially uploaded. + O arquivo foi só subido parcialmente. + + + No file was uploaded. + Non se subiu ningún arquivo. + + + No temporary folder was configured in php.ini. + Ningunha carpeta temporal foi configurada en php.ini. + + + Cannot write temporary file to disk. + Non se puido escribir o arquivo temporal no disco. + + + A PHP extension caused the upload to fail. + Unha extensión de PHP provocou que a subida fallara. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta colección debe conter {{ limit }} elemento ou máis.|Esta colección debe conter {{ limit }} elementos ou máis. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta colección debe conter {{ limit }} elemento ou menos.|Esta colección debe conter {{ limit }} elementos ou menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta colección debe conter exactamente {{ limit }} elemento.|Esta colección debe conter exactamente {{ limit }} elementos. + + + Invalid card number. + Número de tarxeta non válido. + + + Unsupported card type or invalid card number. + Tipo de tarxeta non soportado ou número de tarxeta non válido. + + + This is not a valid International Bank Account Number (IBAN). + Este valor non é un International Bank Account Number (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor non é un ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor non é un ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor non é nin un ISBN-10 válido nin un ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor non é un ISSN válido. + + + This value is not a valid currency. + Este valor non é unha moeda válida. + + + This value should be equal to {{ compared_value }}. + Este valor debería ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor debería ser maior que {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor debería ser maior ou igual que {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor debería ser identico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor debería ser menor que {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor debería ser menor ou igual que {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor non debería ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor non debería ser identico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A proporción da imaxe é demasiado grande ({{ ratio }}). A proporción máxima permitida é {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A proporción da é demasiado pequena ({{ ratio }}). A proporción mínima permitida é {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A imaxe é cadrada ({{ width }}x{{ height }}px). As imáxenes cadradas non están permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A imaxe está orientada horizontalmente ({{ width }}x{{ height }}px). As imáxenes orientadas horizontalmente non están permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A imaxe está orientada verticalmente ({{ width }}x{{ height }}px). As imáxenes orientadas verticalmente non están permitidas. + + + An empty file is not allowed. + Non está permitido un arquivo baleiro. + + + The host could not be resolved. + Non se puido resolver o host. + + + This value does not match the expected {{ charset }} charset. + A codificación de caracteres para este valor debería ser {{ charset }}. + + + + 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 @@ + + + + + + This value should be false. + הערך צריך להיות שקר. + + + This value should be true. + הערך צריך להיות אמת. + + + This value should be of type {{ type }}. + הערך צריך להיות מסוג {{ type }}. + + + This value should be blank. + הערך צריך להיות ריק. + + + The value you selected is not a valid choice. + הערך שבחרת אינו חוקי. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + אתה צריך לבחור לפחות {{ limit }} אפשרויות.|אתה צריך לבחור לפחות {{ limit }} אפשרויות. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + אתה צריך לבחור לכל היותר {{ limit }} אפשרויות.|אתה צריך לבחור לכל היותר {{ limit }} אפשרויות. + + + One or more of the given values is invalid. + אחד או יותר מהערכים אינו חוקי. + + + This field was not expected. + שדה זה לא היה צפוי + + + This field is missing. + שדה זה חסר. + + + This value is not a valid date. + הערך אינו תאריך חוקי. + + + This value is not a valid datetime. + הערך אינו תאריך ושעה חוקיים. + + + This value is not a valid email address. + כתובת המייל אינה תקינה. + + + The file could not be found. + הקובץ לא נמצא. + + + The file is not readable. + לא ניתן לקרוא את הקובץ. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + הקובץ גדול מדי ({{ size }} {{ suffix }}). הגודל המרבי המותר הוא {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + סוג MIME של הקובץ אינו חוקי ({{ type }}). מותרים סוגי MIME {{ types }}. + + + This value should be {{ limit }} or less. + הערך צריל להכיל {{ limit }} תווים לכל היותר. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + הערך ארוך מידי. הוא צריך להכיל {{ limit }} תווים לכל היותר.|הערך ארוך מידי. הוא צריך להכיל {{ limit }} תווים לכל היותר. + + + This value should be {{ limit }} or more. + הערך צריך להכיל {{ limit }} תווים לפחות. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + הערך קצר מידיץ הוא צריך להכיל {{ limit }} תווים לפחות.|הערך קצר מידיץ הוא צריך להכיל {{ limit }} תווים לפחות. + + + This value should not be blank. + הערך לא אמור להיות ריק. + + + This value should not be null. + הערך לא אמור להיות ריק. + + + This value should be null. + הערך צריך להיות ריק. + + + This value is not valid. + הערך אינו חוקי. + + + This value is not a valid time. + הערך אינו זמן תקין. + + + This value is not a valid URL. + זאת אינה כתובת אתר תקינה. + + + The two values should be equal. + שני הערכים צריכים להיות שווים. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + הקובץ גדול מדי. הגודל המרבי המותר הוא {{ limit }} {{ suffix }}. + + + The file is too large. + הקובץ גדול מדי. + + + The file could not be uploaded. + לא ניתן לעלות את הקובץ. + + + This value should be a valid number. + הערך צריך להיות מספר חוקי. + + + This file is not a valid image. + הקובץ הזה אינו תמונה תקינה. + + + This is not a valid IP address. + זו אינה כתובת IP חוקית. + + + This value is not a valid language. + הערך אינו שפה חוקית. + + + This value is not a valid locale. + הערך אינו אזור תקף. + + + This value is not a valid country. + הערך אינו ארץ חוקית. + + + This value is already used. + הערך כבר בשימוש. + + + The size of the image could not be detected. + לא ניתן לקבוע את גודל התמונה. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + רוחב התמונה גדול מדי ({{ width }}px). הרוחב המקסימלי הוא {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + רוחב התמונה קטן מדי ({{ width }}px). הרוחב המינימלי הוא {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + גובה התמונה גדול מדי ({{ height }}px). הגובה המקסימלי הוא {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + גובה התמונה קטן מדי ({{ height }}px). הגובה המינימלי הוא {{ min_height }}px. + + + This value should be the user's current password. + הערך צריך להיות סיסמת המשתמש הנוכחי. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + הערך צריך להיות בדיוק {{ limit }} תווים.|הערך צריך להיות בדיוק {{ limit }} תווים. + + + The file was only partially uploaded. + הקובץ הועלה באופן חלקי. + + + No file was uploaded. + הקובץ לא הועלה. + + + No temporary folder was configured in php.ini. + לא הוגדרה תיקייה זמנית ב php.ini. + + + Cannot write temporary file to disk. + לא ניתן לכתוב קובץ זמני לדיסק. + + + A PHP extension caused the upload to fail. + סיומת PHP גרם להעלאה להיכשל. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + האוסף אמור להכיל {{ limit }} אלמנטים או יותר.|האוסף אמור להכיל {{ limit }} אלמנטים או יותר. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + האוסף אמור להכיל {{ limit }} אלמנטים או פחות.|האוסף אמור להכיל {{ limit }} אלמנטים או פחות. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + האוסף צריך להכיל בדיוק {{ limit }} אלמנטים.|האוסף צריך להכיל בדיוק {{ limit }} אלמנטים. + + + Invalid card number. + מספר הכרטיס אינו חוקי. + + + Unsupported card type or invalid card number. + סוג הכרטיס אינו נתמך או לא חוקי. + + + This is not a valid International Bank Account Number (IBAN). + This is not a valid International Bank Account Number (IBAN). + + + This value is not a valid ISBN-10. + This value is not a valid ISBN-10. + + + This value is not a valid ISBN-13. + This value is not a valid ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + This value is neither a valid ISBN-10 nor a valid ISBN-13. + + + This value is not a valid ISSN. + This value is not a valid ISSN. + + + This value is not a valid currency. + This value is not a valid currency. + + + This value should be equal to {{ compared_value }}. + This value should be equal to {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + This value should be greater than {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + This value should be greater than or equal to {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + This value should be less than {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + This value should be less than or equal to {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + This value should not be equal to {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + + + An empty file is not allowed. + An empty file is not allowed. + + + + 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 @@ + + + + + + This value should be false. + Ova vrijednost treba biti netočna (false). + + + This value should be true. + Ova vrijednost treba biti točna (true). + + + This value should be of type {{ type }}. + Ova vrijednost treba biti tipa {{ type }}. + + + This value should be blank. + Ova vrijednost treba biti prazna. + + + The value you selected is not a valid choice. + Ova vrijednost treba biti jedna od ponuđenih. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Izaberite barem {{ limit }} mogućnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Izaberite najviše {{ limit }} mogućnosti. + + + One or more of the given values is invalid. + Jedna ili više danih vrijednosti nije ispravna. + + + This field was not expected. + Ovo polje nije očekivalo. + + + This field is missing. + Ovo polje nedostaje. + + + This value is not a valid date. + Ova vrijednost nije ispravan datum. + + + This value is not a valid datetime. + Ova vrijednost nije ispravan datum-vrijeme. + + + This value is not a valid email address. + Ova vrijednost nije ispravna e-mail adresa. + + + The file could not be found. + Datoteka ne može biti pronađena. + + + The file is not readable. + Datoteka nije čitljiva. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime tip datoteke nije ispravan ({{ type }}). Dozvoljeni mime tipovi su {{ types }}. + + + This value should be {{ limit }} or less. + Ova vrijednost treba biti {{ limit }} ili manje. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ova vrijednost je predugačka. Treba imati {{ limit }} znakova ili manje. + + + This value should be {{ limit }} or more. + Ova vrijednost treba biti {{ limit }} ili više. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ova vrijednost je prekratka. Treba imati {{ limit }} znakova ili više. + + + This value should not be blank. + Ova vrijednost ne smije biti prazna. + + + This value should not be null. + Ova vrijednost ne smije biti null. + + + This value should be null. + Ova vrijednost treba biti null. + + + This value is not valid. + Ova vrijednost nije ispravna. + + + This value is not a valid time. + Ova vrijednost nije ispravno vrijeme. + + + This value is not a valid URL. + Ova vrijednost nije ispravan URL. + + + The two values should be equal. + Obje vrijednosti trebaju biti jednake. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ova datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The file is too large. + Ova datoteka je prevelika. + + + The file could not be uploaded. + Ova datoteka ne može biti prenesena. + + + This value should be a valid number. + Ova vrijednost treba biti ispravan broj. + + + This file is not a valid image. + Ova datoteka nije ispravna slika. + + + This is not a valid IP address. + Ovo nije ispravna IP adresa. + + + This value is not a valid language. + Ova vrijednost nije ispravan jezik. + + + This value is not a valid locale. + Ova vrijednost nije ispravana regionalna oznaka. + + + This value is not a valid country. + Ova vrijednost nije ispravna zemlja. + + + This value is already used. + Ova vrijednost je već iskorištena. + + + The size of the image could not be detected. + Veličina slike se ne može odrediti. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je prevelika ({{ width }}px). Najveća dozvoljena širina je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premala ({{ width }}px). Najmanja dozvoljena širina je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Visina slike je prevelika ({{ height }}px). Najveća dozvoljena visina je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Visina slike je premala ({{ height }}px). Najmanja dozvoljena visina je {{ min_height }}px. + + + This value should be the user's current password. + Ova vrijednost treba biti trenutna korisnička lozinka. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ova vrijednost treba imati točno {{ limit }} znakova. + + + The file was only partially uploaded. + Datoteka je samo djelomično prenesena. + + + No file was uploaded. + Niti jedna datoteka nije prenesena. + + + No temporary folder was configured in php.ini. + U php.ini datoteci nije konfiguriran privremeni folder. + + + Cannot write temporary file to disk. + Ne mogu zapisati privremenu datoteku na disk. + + + A PHP extension caused the upload to fail. + Prijenos datoteke nije uspio zbog PHP ekstenzije. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ova kolekcija treba sadržavati {{ limit }} ili više elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili više elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili više elemenata. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ova kolekcija treba sadržavati {{ limit }} ili manje elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili manje elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili manje elemenata. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ova kolekcija treba sadržavati točno {{ limit }} element.|Ova kolekcija treba sadržavati točno {{ limit }} elementa.|Ova kolekcija treba sadržavati točno {{ limit }} elemenata. + + + Invalid card number. + Neispravan broj kartice. + + + Unsupported card type or invalid card number. + Neispravan broj kartice ili tip kartice nije podržan. + + + This is not a valid International Bank Account Number (IBAN). + Ova vrijednost nije ispravan međunarodni broj bankovnog računa (IBAN). + + + This value is not a valid ISBN-10. + Ova vrijednost nije ispravan ISBN-10. + + + This value is not a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-10 niti ISBN-13. + + + This value is not a valid ISSN. + Ova vrijednost nije ispravan ISSN. + + + This value is not a valid currency. + Ova vrijednost nije ispravna valuta. + + + This value should be equal to {{ compared_value }}. + Ova vrijednost bi trebala biti jednaka {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ova vrijednost bi trebala biti veća od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ova vrijednost bi trebala biti veća ili jednaka od {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost bi trebala biti {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ova vrijednost bi trebala biti manja od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ova vrijednost bi trebala biti manja ili jednaka {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ova vrijednost ne bi trebala biti {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost ne bi trebala biti {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + Ennek az értéknek hamisnak kell lennie. + + + This value should be true. + Ennek az értéknek igaznak kell lennie. + + + This value should be of type {{ type }}. + Ennek az értéknek {{ type }} típusúnak kell lennie. + + + This value should be blank. + Ennek az értéknek üresnek kell lennie. + + + The value you selected is not a valid choice. + A választott érték érvénytelen. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Legalább {{ limit }} értéket kell kiválasztani.|Legalább {{ limit }} értéket kell kiválasztani. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Legfeljebb {{ limit }} értéket lehet kiválasztani.|Legfeljebb {{ limit }} értéket lehet kiválasztani. + + + One or more of the given values is invalid. + A megadott értékek közül legalább egy érvénytelen. + + + This field was not expected. + Nem várt mező. + + + This field is missing. + Ez a mező hiányzik. + + + This value is not a valid date. + Ez az érték nem egy érvényes dátum. + + + This value is not a valid datetime. + Ez az érték nem egy érvényes időpont. + + + This value is not a valid email address. + Ez az érték nem egy érvényes e-mail cím. + + + The file could not be found. + A fájl nem található. + + + The file is not readable. + A fájl nem olvasható. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + A fájl túl nagy ({{ size }} {{ suffix }}). A legnagyobb megengedett méret {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + A fájl MIME típusa érvénytelen ({{ type }}). Az engedélyezett MIME típusok: {{ types }}. + + + This value should be {{ limit }} or less. + Ez az érték legfeljebb {{ limit }} lehet. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ez az érték túl hosszú. Legfeljebb {{ limit }} karaktert tartalmazhat.|Ez az érték túl hosszú. Legfeljebb {{ limit }} karaktert tartalmazhat. + + + This value should be {{ limit }} or more. + Ez az érték legalább {{ limit }} kell, hogy legyen. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ez az érték túl rövid. Legalább {{ limit }} karaktert kell tartalmaznia.|Ez az érték túl rövid. Legalább {{ limit }} karaktert kell tartalmaznia. + + + This value should not be blank. + Ez az érték nem lehet üres. + + + This value should not be null. + Ez az érték nem lehet null. + + + This value should be null. + Ennek az értéknek nullnak kell lennie. + + + This value is not valid. + Ez az érték nem érvényes. + + + This value is not a valid time. + Ez az érték nem egy érvényes időpont. + + + This value is not a valid URL. + Ez az érték nem egy érvényes URL. + + + The two values should be equal. + A két értéknek azonosnak kell lennie. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + A fájl túl nagy. A megengedett maximális méret: {{ limit }} {{ suffix }}. + + + The file is too large. + A fájl túl nagy. + + + The file could not be uploaded. + A fájl nem tölthető fel. + + + This value should be a valid number. + Ennek az értéknek érvényes számnak kell lennie. + + + This file is not a valid image. + Ez a fájl nem egy érvényes kép. + + + This is not a valid IP address. + Ez az érték nem egy érvényes IP cím. + + + This value is not a valid language. + Ez az érték nem egy érvényes nyelv. + + + This value is not a valid locale. + Ez az érték nem egy érvényes területi beállítás. + + + This value is not a valid country. + Ez az érték nem egy érvényes ország. + + + This value is already used. + Ez az érték már használatban van. + + + The size of the image could not be detected. + A kép méretét nem lehet megállapítani. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A kép szélessége túl nagy ({{ width }}px). A megengedett legnagyobb szélesség {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A kép szélessége túl kicsi ({{ width }}px). Az elvárt legkisebb szélesség {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A kép magassága túl nagy ({{ height }}px). A megengedett legnagyobb magasság {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A kép magassága túl kicsi ({{ height }}px). Az elvárt legkisebb magasság {{ min_height }}px. + + + This value should be the user's current password. + Ez az érték a felhasználó jelenlegi jelszavával kell megegyezzen. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ennek az értéknek pontosan {{ limit }} karaktert kell tartalmaznia.|Ennek az értéknek pontosan {{ limit }} karaktert kell tartalmaznia. + + + The file was only partially uploaded. + A fájl csak részben lett feltöltve. + + + No file was uploaded. + Nem lett fájl feltöltve. + + + No temporary folder was configured in php.ini. + Nincs ideiglenes könyvtár beállítva a php.ini-ben. + + + Cannot write temporary file to disk. + Az ideiglenes fájl nem írható a lemezre. + + + A PHP extension caused the upload to fail. + Egy PHP bővítmény miatt a feltöltés nem sikerült. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ennek a gyűjteménynek legalább {{ limit }} elemet kell tartalmaznia.|Ennek a gyűjteménynek legalább {{ limit }} elemet kell tartalmaznia. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ez a gyűjtemény legfeljebb {{ limit }} elemet tartalmazhat.|Ez a gyűjtemény legfeljebb {{ limit }} elemet tartalmazhat. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ennek a gyűjteménynek pontosan {{ limit }} elemet kell tartalmaznia.|Ennek a gyűjteménynek pontosan {{ limit }} elemet kell tartalmaznia. + + + Invalid card number. + Érvénytelen kártyaszám. + + + Unsupported card type or invalid card number. + Nem támogatott kártyatípus vagy érvénytelen kártyaszám. + + + This is not a valid International Bank Account Number (IBAN). + Érvénytelen nemzetközi bankszámlaszám (IBAN). + + + This value is not a valid ISBN-10. + Ez az érték nem egy érvényes ISBN-10. + + + This value is not a valid ISBN-13. + Ez az érték nem egy érvényes ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ez az érték nem egy érvényes ISBN-10 vagy ISBN-13. + + + This value is not a valid ISSN. + Ez az érték nem egy érvényes ISSN. + + + This value is not a valid currency. + Ez az érték nem egy érvényes pénznem. + + + This value should be equal to {{ compared_value }}. + Ez az érték legyen {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ez az érték nagyobb legyen, mint {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ez az érték nagyobb vagy egyenlő legyen, mint {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ez az érték ugyanolyan legyen, mint {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ez az érték kisebb legyen, mint {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ez az érték kisebb vagy egyenlő legyen, mint {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ez az érték ne legyen {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ez az érték ne legyen ugyanolyan, mint {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A képarány túl nagy ({{ ratio }}). A megengedett legnagyobb képarány {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A képarány túl kicsi ({{ ratio }}). A megengedett legkisebb képarány {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A kép négyzet alakú ({{ width }}x{{ height }}px). A négyzet alakú képek nem engedélyezettek. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A kép fekvő tájolású ({{ width }}x{{ height }}px). A fekvő tájolású képek nem engedélyezettek. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A kép álló tájolású ({{ width }}x{{ height }}px). Az álló tájolású képek nem engedélyezettek. + + + An empty file is not allowed. + Üres fájl nem megengedett. + + + This value does not match the expected {{ charset }} charset. + Ez az érték nem az elvárt {{ charset }} karakterkódolást használja. + + + + 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 @@ + + + + + + This value should be false. + Արժեքը պետք է լինի կեղծ. + + + This value should be true. + Արժեքը պետք է լինի ճշմարիտ. + + + This value should be of type {{ type }}. + Արժեքը պետք է լինի {{ type }} տեսակի. + + + This value should be blank. + Արժեքը պետք է լինի դատարկ. + + + The value you selected is not a valid choice. + Ձեր ընտրած արժեքը անթույլատրելի է. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Դուք պետք է ընտրեք ամենաքիչը {{ limit }} տարբերակներ. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Դուք պետք է ընտրեք ոչ ավելի քան {{ limit }} տարբերակներ. + + + One or more of the given values is invalid. + Մեկ կամ ավելի տրված արժեքները անթույլատրելի են. + + + This field was not expected. + Այս դաշտը չի սպասվում. + + + This field is missing. + Այս դաշտը բացակայում է. + + + This value is not a valid date. + Արժեքը սխալ ամսաթիվ է. + + + This value is not a valid datetime. + Ամսաթվի և ժամանակի արժեքը անթույլատրելի է. + + + This value is not a valid email address. + Էլ-փոստի արժեքը անթույլատրելի է. + + + The file could not be found. + Ֆայլը չի գտնվել. + + + The file is not readable. + Ֆայլը անընթեռնելի է. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Ֆայլը չափազանց մեծ է ({{ size }} {{ suffix }}): Մաքսիմալ թույլատրելի չափսը՝ {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME-տեսակը անթույլատրելի է({{ type }}): Ֆայլերի թույլատրելի MIME-տեսակներն են: {{ types }}. + + + This value should be {{ limit }} or less. + Արժեքը պետք է լինի {{ limit }} կամ փոքր. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Արժեքը չափազանց երկար է: Պետք է լինի {{ limit }} կամ ավել սիմվոլներ. + + + This value should be {{ limit }} or more. + Արժեքը պետ է լինի {{ limit }} կամ շատ. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Արժեքը չափազանց կարճ է: Պետք է լինի {{ limit }} կամ ավելի սիմվոլներ. + + + This value should not be blank. + Արժեքը չպետք է դատարկ լինի. + + + This value should not be null. + Արժեքը չպետք է լինի null. + + + This value should be null. + Արժեքը պետք է լինի null. + + + This value is not valid. + Անթույլատրելի արժեք. + + + This value is not a valid time. + Ժամանակի արժեքը անթույլատրելի է. + + + This value is not a valid URL. + Արժեքը URL չէ. + + + The two values should be equal. + Երկու արժեքները պետք է նույնը լինեն. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ֆայլը չափազանց մեծ է: Մաքսիմալ թույլատրելի չափսը {{ limit }} {{ suffix }} է. + + + The file is too large. + Ֆայլը չափազանց մեծ է. + + + The file could not be uploaded. + Ֆայլը չի կարող բեռնվել. + + + This value should be a valid number. + Արժեքը պետք է լինի թիվ. + + + This value is not a valid country. + Արժեքը պետք է լինի երկիր. + + + This file is not a valid image. + Ֆայլը նկարի թույլատրելի ֆորմատ չէ. + + + This is not a valid IP address. + Արժեքը թույլատրելի IP հասցե չէ. + + + This value is not a valid language. + Արժեքը թույլատրելի լեզու չէ. + + + This value is not a valid locale. + Արժեքը չի հանդիսանում թույլատրելի տեղայնացում. + + + This value is already used. + Այդ արժեքը արդեն օգտագործվում է. + + + The size of the image could not be detected. + Նկարի չափսերը չստացվեց որոշել. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Նկարի լայնությունը չափազանց մեծ է({{ width }}px). Մաքսիմալ չափն է {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Նկարի լայնությունը չափազանց փոքր է ({{ width }}px). Մինիմալ չափն է {{ min_ width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Նկարի բարձրությունը չափազանց մեծ է ({{ height }}px). Մաքսիմալ չափն է {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Նկարի բարձրությունը չափազանց փոքր է ({{ height }}px). Մինիմալ չափն է {{ min_height }}px. + + + This value should be the user's current password. + Այս արժեքը պետք է լինի օգտագործողի ներկա ծածկագիրը. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Այս արժեքը պետք է ունենա ճիշտ {{ limit }} սիմվոլներ. + + + + 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 @@ + + + + + + This value should be false. + Nilai ini harus bernilai salah. + + + This value should be true. + Nilai ini harus bernilai benar. + + + This value should be of type {{ type }}. + Nilai ini harus bertipe {{ type }}. + + + This value should be blank. + Nilai ini harus kosong. + + + The value you selected is not a valid choice. + Nilai yang dipilih tidak tepat. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Anda harus memilih paling tidak {{ limit }} pilihan. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Anda harus memilih paling banyak {{ limit }} pilihan. + + + One or more of the given values is invalid. + Satu atau lebih nilai yang diberikan tidak sah. + + + This field was not expected. + Bidang ini tidak diharapkan. + + + This field is missing. + Bidang ini hilang. + + + This value is not a valid date. + Nilai ini bukan merupakan tanggal yang sah. + + + This value is not a valid datetime. + Nilai ini bukan merupakan tanggal dan waktu yang sah. + + + This value is not a valid email address. + Nilai ini bukan alamat email yang sah. + + + The file could not be found. + Berkas tidak ditemukan. + + + The file is not readable. + Berkas tidak bisa dibaca. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Ukuran berkas terlalu besar ({{ size }} {{ suffix }}). Ukuran maksimum yang diizinkan adalah {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Jenis berkas ({{ type }}) tidak sah. Jenis berkas yang diijinkan adalah {{ types }}. + + + This value should be {{ limit }} or less. + Nilai ini harus {{ limit }} atau kurang. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Nilai ini terlalu panjang. Seharusnya {{ limit }} karakter atau kurang. + + + This value should be {{ limit }} or more. + Nilai ini harus {{ limit }} atau lebih. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Nilai ini terlalu pendek. Seharusnya {{ limit }} karakter atau lebih. + + + This value should not be blank. + Nilai ini tidak boleh kosong. + + + This value should not be null. + Nilai ini tidak boleh 'null'. + + + This value should be null. + Nilai ini harus 'null'. + + + This value is not valid. + Nilai ini tidak sah. + + + This value is not a valid time. + Nilai ini bukan merupakan waktu yang sah. + + + This value is not a valid URL. + Nilai ini bukan URL yang sah. + + + The two values should be equal. + Isi keduanya harus sama. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ukuran berkas terlalu besar. Ukuran maksimum yang diijinkan adalah {{ limit }} {{ suffix }}. + + + The file is too large. + Ukuran berkas terlalu besar. + + + The file could not be uploaded. + Berkas tidak dapat diunggah. + + + This value should be a valid number. + Nilai ini harus angka yang sah. + + + This file is not a valid image. + Berkas ini tidak termasuk gambar. + + + This is not a valid IP address. + Ini bukan alamat IP yang sah. + + + This value is not a valid language. + Nilai ini bukan bahasa yang sah. + + + This value is not a valid locale. + Nilai ini bukan lokal yang sah. + + + This value is not a valid country. + Nilai ini bukan negara yang sah. + + + This value is already used. + Nilai ini sudah digunakan. + + + The size of the image could not be detected. + Ukuran dari gambar tidak bisa dideteksi. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Lebar gambar terlalu besar ({{ width }}px). Ukuran lebar maksimum adalah {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Lebar gambar terlalu kecil ({{ width }}px). Ukuran lebar minimum yang diharapkan adalah {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Tinggi gambar terlalu besar ({{ height }}px). Ukuran tinggi maksimum adalah {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Tinggi gambar terlalu kecil ({{ height }}px). Ukuran tinggi minimum yang diharapkan adalah {{ min_height }}px. + + + This value should be the user's current password. + Nilai ini harus kata sandi pengguna saat ini. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Nilai ini harus memiliki tepat {{ limit }} karakter. + + + The file was only partially uploaded. + Berkas hanya terunggah sebagian. + + + No file was uploaded. + Tidak ada berkas terunggah. + + + No temporary folder was configured in php.ini. + Direktori sementara tidak dikonfiguasi pada php.ini. + + + Cannot write temporary file to disk. + Tidak dapat menuliskan berkas sementara ke dalam media penyimpanan. + + + A PHP extension caused the upload to fail. + Sebuah ekstensi PHP menyebabkan kegagalan unggah. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Kumpulan ini harus memiliki {{ limit }} elemen atau lebih. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Kumpulan ini harus memiliki kurang dari {{ limit }} elemen. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Kumpulan ini harus memiliki tepat {{ limit }} elemen. + + + Invalid card number. + Nomor kartu tidak sah. + + + Unsupported card type or invalid card number. + Jenis kartu tidak didukung atau nomor kartu tidak sah. + + + This is not a valid International Bank Account Number (IBAN). + Ini bukan Nomor Rekening Bank Internasional (IBAN) yang sah. + + + This value is not a valid ISBN-10. + Nilai ini bukan ISBN-10 yang sah. + + + This value is not a valid ISBN-13. + Nilai ini bukan ISBN-13 yang sah. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Nilai ini bukan ISBN-10 maupun ISBN-13 yang sah. + + + This value is not a valid ISSN. + Nilai ini bukan ISSN yang sah. + + + This value is not a valid currency. + Nilai ini bukan mata uang yang sah. + + + This value should be equal to {{ compared_value }}. + Nilai ini seharusnya sama dengan {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Nilai ini seharusnya lebih dari {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Nilai ini seharusnya lebih dari atau sama dengan {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Nilai ini seharusnya identik dengan {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Nilai ini seharusnya kurang dari {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Nilai ini seharusnya kurang dari atau sama dengan {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Nilai ini seharusnya tidak sama dengan {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Nilai ini seharusnya tidak identik dengan {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + Questo valore dovrebbe essere falso. + + + This value should be true. + Questo valore dovrebbe essere vero. + + + This value should be of type {{ type }}. + Questo valore dovrebbe essere di tipo {{ type }}. + + + This value should be blank. + Questo valore dovrebbe essere vuoto. + + + The value you selected is not a valid choice. + Questo valore dovrebbe essere una delle opzioni disponibili. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Si dovrebbe selezionare almeno {{ limit }} opzione.|Si dovrebbero selezionare almeno {{ limit }} opzioni. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Si dovrebbe selezionare al massimo {{ limit }} opzione.|Si dovrebbero selezionare al massimo {{ limit }} opzioni. + + + One or more of the given values is invalid. + Uno o più valori inseriti non sono validi. + + + This field was not expected. + Questo campo non è stato previsto. + + + This field is missing. + Questo campo è manca. + + + This value is not a valid date. + Questo valore non è una data valida. + + + This value is not a valid datetime. + Questo valore non è una data e ora valida. + + + This value is not a valid email address. + Questo valore non è un indirizzo email valido. + + + The file could not be found. + Non è stato possibile trovare il file. + + + The file is not readable. + Il file non è leggibile. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Il file è troppo grande ({{ size }} {{ suffix }}). La dimensione massima consentita è {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Il mime type del file non è valido ({{ type }}). I tipi permessi sono {{ types }}. + + + This value should be {{ limit }} or less. + Questo valore dovrebbe essere {{ limit }} o inferiore. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Questo valore è troppo lungo. Dovrebbe essere al massimo di {{ limit }} carattere.|Questo valore è troppo lungo. Dovrebbe essere al massimo di {{ limit }} caratteri. + + + This value should be {{ limit }} or more. + Questo valore dovrebbe essere {{ limit }} o superiore. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Questo valore è troppo corto. Dovrebbe essere almeno di {{ limit }} carattere.|Questo valore è troppo corto. Dovrebbe essere almeno di {{ limit }} caratteri. + + + This value should not be blank. + Questo valore non dovrebbe essere vuoto. + + + This value should not be null. + Questo valore non dovrebbe essere nullo. + + + This value should be null. + Questo valore dovrebbe essere nullo. + + + This value is not valid. + Questo valore non è valido. + + + This value is not a valid time. + Questo valore non è un'ora valida. + + + This value is not a valid URL. + Questo valore non è un URL valido. + + + The two values should be equal. + I due valori dovrebbero essere uguali. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Il file è troppo grande. La dimensione massima è {{ limit }} {{ suffix }}. + + + The file is too large. + Il file è troppo grande. + + + The file could not be uploaded. + Il file non può essere caricato. + + + This value should be a valid number. + Questo valore dovrebbe essere un numero. + + + This file is not a valid image. + Questo file non è una immagine valida. + + + This is not a valid IP address. + Questo valore non è un indirizzo IP valido. + + + This value is not a valid language. + Questo valore non è una lingua valida. + + + This value is not a valid locale. + Questo valore non è una impostazione regionale valida. + + + This value is not a valid country. + Questo valore non è una nazione valida. + + + This value is already used. + Questo valore è già stato utilizzato. + + + The size of the image could not be detected. + La dimensione dell'immagine non può essere determinata. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + La larghezza dell'immagine è troppo grande ({{ width }}px). La larghezza massima è di {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + La larghezza dell'immagine è troppo piccola ({{ width }}px). La larghezza minima è di {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + L'altezza dell'immagine è troppo grande ({{ height }}px). L'altezza massima è di {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + L'altezza dell'immagine è troppo piccola ({{ height }}px). L'altezza minima è di {{ min_height }}px. + + + This value should be the user's current password. + Questo valore dovrebbe essere la password attuale dell'utente. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Questo valore dovrebbe contenere esattamente {{ limit }} carattere.|Questo valore dovrebbe contenere esattamente {{ limit }} caratteri. + + + The file was only partially uploaded. + Il file è stato caricato solo parzialmente. + + + No file was uploaded. + Nessun file è stato caricato. + + + No temporary folder was configured in php.ini. + Nessuna cartella temporanea è stata configurata nel php.ini. + + + Cannot write temporary file to disk. + Impossibile scrivere il file temporaneo sul disco. + + + A PHP extension caused the upload to fail. + Un'estensione PHP ha causato il fallimento del caricamento. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Questa collezione dovrebbe contenere almeno {{ limit }} elemento.|Questa collezione dovrebbe contenere almeno {{ limit }} elementi. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Questa collezione dovrebbe contenere massimo {{ limit }} elemento.|Questa collezione dovrebbe contenere massimo {{ limit }} elementi. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Questa collezione dovrebbe contenere esattamente {{ limit }} elemento.|Questa collezione dovrebbe contenere esattamente {{ limit }} elementi. + + + Invalid card number. + Numero di carta non valido. + + + Unsupported card type or invalid card number. + Tipo di carta non supportato o numero non valido. + + + This is not a valid International Bank Account Number (IBAN). + Questo valore non è un IBAN (International Bank Account Number) valido. + + + This value is not a valid ISBN-10. + Questo valore non è un codice ISBN-10 valido. + + + This value is not a valid ISBN-13. + Questo valore non è un codice ISBN-13 valido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Questo valore non è un codice ISBN-10 o ISBN-13 valido. + + + This value is not a valid ISSN. + Questo valore non è un codice ISSN valido. + + + This value is not a valid currency. + Questo valore non è una valuta valida. + + + This value should be equal to {{ compared_value }}. + Questo valore dovrebbe essere uguale a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Questo valore dovrebbe essere maggiore di {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Questo valore dovrebbe essere maggiore o uguale a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Questo valore dovrebbe essere identico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Questo valore dovrebbe essere minore di {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Questo valore dovrebbe essere minore o uguale a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Questo valore dovrebbe essere diverso da {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Questo valore dovrebbe essere diverso da {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Il rapporto di aspetto dell'immagine è troppo grande ({{ ratio }}). Il rapporto massimo consentito è {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Il rapporto di aspetto dell'immagine è troppo piccolo ({{ ratio }}). Il rapporto minimo consentito è {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + L'immagine è quadrata ({{ width }}x{{ height }}px). Le immagini quadrate non sono consentite. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + L'immagine è orizzontale ({{ width }}x{{ height }}px). Le immagini orizzontali non sono consentite. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + L'immagine è verticale ({{ width }}x{{ height }}px). Le immagini verticali non sono consentite. + + + An empty file is not allowed. + Un file vuoto non è consentito. + + + + 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 @@ + + + + + + This value should be false. + falseでなければなりません。 + + + This value should be true. + trueでなければなりません。 + + + This value should be of type {{ type }}. + 型は{{ type }}でなければなりません。 + + + This value should be blank. + 空でなければなりません。 + + + The value you selected is not a valid choice. + 有効な選択肢ではありません。 + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + {{ limit }}個以上選択してください。 + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + {{ limit }}個以内で選択してください。 + + + One or more of the given values is invalid. + 無効な選択肢が含まれています。 + + + This field was not expected. + このフィールドは予期されていませんでした。 + + + This field is missing. + このフィールドは、欠落しています。 + + + This value is not a valid date. + 有効な日付ではありません。 + + + This value is not a valid datetime. + 有効な日時ではありません。 + + + This value is not a valid email address. + 有効なメールアドレスではありません。 + + + The file could not be found. + ファイルが見つかりません。 + + + The file is not readable. + ファイルを読み込めません。 + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + ファイルのサイズが大きすぎます({{ size }} {{ suffix }})。有効な最大サイズは{{ limit }} {{ suffix }}です。 + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + ファイルのMIMEタイプが無効です({{ type }})。有効なMIMEタイプは{{ types }}です。 + + + This value should be {{ limit }} or less. + {{ limit }}以下でなければなりません。 + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + 値が長すぎます。{{ limit }}文字以内でなければなりません。 + + + This value should be {{ limit }} or more. + {{ limit }}以上でなければなりません。 + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + 値が短すぎます。{{ limit }}文字以上でなければなりません。 + + + This value should not be blank. + 空であってはなりません。 + + + This value should not be null. + nullであってはなりません。 + + + This value should be null. + nullでなければなりません。 + + + This value is not valid. + 有効な値ではありません。 + + + This value is not a valid time. + 有効な時刻ではありません。 + + + This value is not a valid URL. + 有効なURLではありません。 + + + The two values should be equal. + 2つの値が同じでなければなりません。 + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + ファイルのサイズが大きすぎます。有効な最大サイズは{{ limit }} {{ suffix }}です。 + + + The file is too large. + ファイルのサイズが大きすぎます。 + + + The file could not be uploaded. + ファイルをアップロードできませんでした。 + + + This value should be a valid number. + 有効な数字ではありません。 + + + This file is not a valid image. + ファイルが画像ではありません。 + + + This is not a valid IP address. + 有効なIPアドレスではありません。 + + + This value is not a valid language. + 有効な言語名ではありません。 + + + This value is not a valid locale. + 有効なロケールではありません。 + + + This value is not a valid country. + 有効な国名ではありません。 + + + This value is already used. + 既に使用されています。 + + + The size of the image could not be detected. + 画像のサイズが検出できません。 + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 画像の幅が大きすぎます({{ width }}ピクセル)。{{ max_width }}ピクセルまでにしてください。 + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 画像の幅が小さすぎます({{ width }}ピクセル)。{{ min_width }}ピクセル以上にしてください。 + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 画像の高さが大きすぎます({{ height }}ピクセル)。{{ max_height }}ピクセルまでにしてください。 + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 画像の高さが小さすぎます({{ height }}ピクセル)。{{ min_height }}ピクセル以上にしてください。 + + + This value should be the user current password. + ユーザーの現在のパスワードでなければなりません。 + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + ちょうど{{ limit }}文字でなければなりません。 + + + The file was only partially uploaded. + ファイルのアップロードは完全ではありません。 + + + No file was uploaded. + ファイルがアップロードされていません。 + + + No temporary folder was configured in php.ini. + php.iniで一時フォルダが設定されていません。 + + + Cannot write temporary file to disk. + 一時ファイルをディスクに書き込むことができません。 + + + A PHP extension caused the upload to fail. + PHP拡張によってアップロードに失敗しました。 + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + {{ limit }}個以上の要素を含んでなければいけません。 + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + 要素は{{ limit }}個までです。 + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + 要素はちょうど{{ limit }}個でなければなりません。 + + + Invalid card number. + 無効なカード番号です。 + + + Unsupported card type or invalid card number. + 未対応のカード種類又は無効なカード番号です。 + + + This is not a valid International Bank Account Number (IBAN). + 有効なIBANコードではありません。 + + + This value is not a valid ISBN-10. + 有効なISBN-10コードではありません。 + + + This value is not a valid ISBN-13. + 有効なISBN-13コードではありません。 + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + 有効なISBN-10コード又はISBN-13コードではありません。 + + + This value is not a valid ISSN. + 有効なISSNコードではありません。 + + + This value is not a valid currency. + 有効な貨幣ではありません。 + + + This value should be equal to {{ compared_value }}. + {{ compared_value }}と等しくなければなりません。 + + + This value should be greater than {{ compared_value }}. + {{ compared_value }}より大きくなければなりません。 + + + This value should be greater than or equal to {{ compared_value }}. + {{ compared_value }}以上でなければなりません。 + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + {{ compared_value_type }}としての{{ compared_value }}と等しくなければなりません。 + + + This value should be less than {{ compared_value }}. + {{ compared_value }}未満でなければなりません。 + + + This value should be less than or equal to {{ compared_value }}. + {{ compared_value }}以下でなければなりません。 + + + This value should not be equal to {{ compared_value }}. + {{ compared_value }}と等しくてはいけません。 + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + {{ compared_value_type }}としての{{ compared_value }}と等しくてはいけません。 + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 画像のアスペクト比が大きすぎます({{ ratio }})。{{ max_ratio }}までにしてください。 + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 画像のアスペクト比が小さすぎます({{ ratio }})。{{ min_ratio }}以上にしてください。 + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + 画像が正方形になっています({{ width }}x{{ height }}ピクセル)。正方形の画像は許可されていません。 + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + 画像が横向きになっています({{ width }}x{{ height }}ピクセル)。横向きの画像は許可されていません。 + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + 画像が縦向きになっています({{ width }}x{{ height }}ピクセル)。縦向きの画像は許可されていません。 + + + An empty file is not allowed. + 空のファイルは許可されていません。 + + + The host could not be resolved. + ホストを解決できませんでした。 + + + This value does not match the expected {{ charset }} charset. + この値は予期される文字コード({{ charset }})と異なります。 + + + + 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 @@ + + + + + + This value should be false. + Dëse Wäert sollt falsch sinn. + + + This value should be true. + Dëse Wäert sollt wouer sinn. + + + This value should be of type {{ type }}. + Dëse Wäert sollt vum Typ {{ type }} sinn. + + + This value should be blank. + Dëse Wäert sollt eidel sinn. + + + The value you selected is not a valid choice. + Dëse Wäert sollt enger vun de Wielméiglechkeeten entspriechen. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Dir sollt mindestens {{ limit }} Méiglechkeete wielen. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Dir sollt héchstens {{ limit }} Méiglechkeete wielen. + + + One or more of the given values is invalid. + Een oder méi vun de Wäerter ass ongëlteg. + + + The fields {{ fields }} were not expected. + D'Felder {{ fields }} goufen net erwaart. + + + The fields {{ fields }} are missing. + D'Felder {{ fields }} feelen. + + + This value is not a valid date. + Dëse Wäert entsprécht kenger gëlteger Datumsangab. + + + This value is not a valid datetime. + Dëse Wäert entsprécht kenger gëlteger Datums- an Zäitangab. + + + This value is not a valid email address. + Dëse Wäert ass keng gëlteg Email-Adress. + + + The file could not be found. + De Fichier gouf net fonnt. + + + The file is not readable. + De Fichier ass net liesbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + De Fichier ass ze grouss ({{ size }} {{ suffix }}). Déi zougeloosse Maximalgréisst bedréit {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Den Typ vum Fichier ass ongëlteg ({{ type }}). Erlaabten Type sinn {{ types }}. + + + This value should be {{ limit }} or less. + Dëse Wäert soll méi kleng oder gläich {{ limit }} sinn. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Dës Zeecheketten ass ze laang. Se sollt héchstens {{ limit }} Zeechen hunn. + + + This value should be {{ limit }} or more. + Dëse Wäert sollt méi grouss oder gläich {{ limit }} sinn. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Dës Zeecheketten ass ze kuerz. Se sollt mindestens {{ limit }} Zeechen hunn. + + + This value should not be blank. + Dëse Wäert sollt net eidel sinn. + + + This value should not be null. + Dëst sollt keen Null-Wäert sinn. + + + This value should be null. + Dëst sollt keen Null-Wäert sinn. + + + This value is not valid. + Dëse Wäert ass net gëlteg. + + + This value is not a valid time. + Dëse Wäert entsprécht kenger gëlteger Zäitangab. + + + This value is not a valid URL. + Dëse Wäert ass keng gëlteg URL. + + + The two values should be equal. + Béid Wäerter sollten identesch sinn. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + De fichier ass ze grouss. Déi maximal Gréisst dierf {{ limit }} {{ suffix }} net depasséieren. + + + The file is too large. + De Fichier ass ze grouss. + + + The file could not be uploaded. + De Fichier konnt net eropgeluede ginn. + + + This value should be a valid number. + Dëse Wäert sollt eng gëlteg Zuel sinn. + + + This file is not a valid image. + Dëse Fichier ass kee gëltegt Bild. + + + This is not a valid IP address. + Dëst ass keng gëlteg IP-Adress. + + + This value is not a valid language. + Dëse Wäert aentsprécht kenger gëlteger Sprooch. + + + This value is not a valid locale. + Dëse Wäert entsprécht kengem gëltege Gebittsschema. + + + This value is not a valid country. + Dëse Wäert entsprécht kengem gëltege Land. + + + This value is already used. + Dëse Wäert gëtt scho benotzt. + + + The size of the image could not be detected. + D'Gréisst vum Bild konnt net detektéiert ginn. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + D'Breet vum Bild ass ze grouss ({{ width }}px). Déi erlaabte maximal Breet ass {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + D'Breet vum Bild ass ze kleng ({{ width }}px). Déi minimal Breet ass {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + D'Héicht vum Bild ass ze grouss ({{ height }}px). Déi erlaabte maximal Héicht ass {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + D'Héicht vum Bild ass ze kleng ({{ height }}px). Déi minimal Héicht ass {{ min_height }}px. + + + This value should be the user's current password. + Dëse Wäert sollt dem aktuelle Benotzerpasswuert entspriechen. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Dëse Wäert sollt exactly {{ limit }} Buschtaf hunn.|Dëse Wäert sollt exakt {{ limit }} Buschtawen hunn. + + + The file was only partially uploaded. + De Fichier gouf just deelweis eropgelueden. + + + No file was uploaded. + Et gouf kee Fichier eropgelueden. + + + No temporary folder was configured in php.ini. + Et gouf keen temporären Dossier an der php.ini konfiguréiert. + + + Cannot write temporary file to disk. + Den temporäre Fichier kann net gespäichert ginn. + + + A PHP extension caused the upload to fail. + Eng PHP-Erweiderung huet den Upload verhënnert. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Dës Sammlung sollt {{ limit }} oder méi Elementer hunn. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Dës Sammlung sollt {{ limit }} oder manner Elementer hunn. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Dës Sammlung sollt exakt {{ limit }} Element hunn.|Dës Sammlung sollt exakt {{ limit }} Elementer hunn. + + + Invalid card number. + Ongëlteg Kaartennummer. + + + Unsupported card type or invalid card number. + Net ënnerstëtzte Kaartentyp oder ongëlteg Kaartennummer. + + + This is not a valid International Bank Account Number (IBAN). + Dëst ass keng gëlteg IBAN-Kontonummer. + + + This value is not a valid ISBN-10. + Dëse Wäert ass keng gëlteg ISBN-10. + + + This value is not a valid ISBN-13. + Dëse Wäert ass keng gëlteg ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Dëse Wäert ass weder eng gëlteg ISBN-10 nach eng gëlteg ISBN-13. + + + This value is not a valid ISSN. + Dëse Wäert ass keng gëlteg ISSN. + + + This value is not a valid currency. + Dëse Wäert ass keng gëlteg Währung. + + + This value should be equal to {{ compared_value }}. + Dëse Wäert sollt {{ compared_value }} sinn. + + + This value should be greater than {{ compared_value }}. + Dëse Wäert sollt méi grouss wéi {{ compared_value }} sinn. + + + This value should be greater than or equal to {{ compared_value }}. + Dëse Wäert sollt méi grouss wéi oder gläich {{ compared_value }} sinn. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Dëse Wäert sollt identesch si mat {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Dëse Wäert sollt méi kleng wéi {{ compared_value }} sinn. + + + This value should be less than or equal to {{ compared_value }}. + Dëse Wäert sollt méi kleng wéi oder gläich {{ compared_value }} sinn. + + + This value should not be equal to {{ compared_value }}. + Dëse Wäert sollt net {{ compared_value }} sinn. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Dëse Wäert sollt net identesch si mat {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + D'Säiteverhältnis vum Bild ass ze grouss ({{ ratio }}). Den erlaabte Maximalwäert ass {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + D'Säiteverhältnis vum Bild ass ze kleng ({{ ratio }}). Den erwaarte Minimalwäert ass {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + D'Bild ass quadratesch ({{ width }}x{{ height }}px). Quadratesch Biller sinn net erlaabt. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + D'Bild ass am Queeschformat ({{ width }}x{{ height }}px). Biller am Queeschformat sinn net erlaabt. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + D'Bild ass am Héichformat ({{ width }}x{{ height }}px). Biller am Héichformat sinn net erlaabt. + + + + 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 @@ + + + + + + This value should be false. + Reikšmė turi būti neigiama. + + + This value should be true. + Reikšmė turi būti teigiama. + + + This value should be of type {{ type }}. + Šios reikšmės tipas turi būti {{ type }}. + + + This value should be blank. + Ši reikšmė turi būti tuščia. + + + The value you selected is not a valid choice. + Neteisingas pasirinkimas. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Turite pasirinkti bent {{ limit }} variantą.|Turite pasirinkti bent {{ limit }} variantus.|Turite pasirinkti bent {{ limit }} variantų. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Turite pasirinkti ne daugiau kaip {{ limit }} variantą.|Turite pasirinkti ne daugiau kaip {{ limit }} variantus.|Turite pasirinkti ne daugiau kaip {{ limit }} variantų. + + + One or more of the given values is invalid. + Viena ar daugiau įvestų reikšmių yra netinkamos. + + + This field was not expected. + Nebuvo tikimasi Šis laukas. + + + This field is missing. + Šiame lauke yra dingęs. + + + This value is not a valid date. + Ši reikšmė nėra data. + + + This value is not a valid datetime. + Ši reikšmė nera data ir laikas. + + + This value is not a valid email address. + Ši reikšmė nėra tinkamas el. pašto adresas. + + + The file could not be found. + Byla nerasta. + + + The file is not readable. + Negalima nuskaityti bylos. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Byla yra per didelė ({{ size }} {{ suffix }}). Maksimalus dydis {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Netinkamas bylos tipas (mime type) ({{ type }}). Galimi bylų tipai {{ types }}. + + + This value should be {{ limit }} or less. + Reikšmė turi būti {{ limit }} arba mažiau. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Per didelis simbolių skaičius. Turi susidaryti iš {{ limit }} arba mažiau simbolių.|Per didelis simbolių skaičius. Turi susidaryti iš {{ limit }} arba mažiau simbolių.|Per didelis simbolių skaičius. Turi susidaryti iš {{ limit }} arba mažiau simbolių. + + + This value should be {{ limit }} or more. + Reikšmė turi būti {{ limit }} arba daugiau. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Per mažas simbolių skaičius. Turi susidaryti iš {{ limit }} arba daugiau simbolių.|Per mažas simbolių skaičius. Turi susidaryti iš {{ limit }} arba daugiau simbolių.|Per mažas simbolių skaičius. Turi susidaryti iš {{ limit }} arba daugiau simbolių. + + + This value should not be blank. + Ši reikšmė negali būti tuščia. + + + This value should not be null. + Ši reikšmė negali būti null. + + + This value should be null. + Ši reikšmė turi būti null. + + + This value is not valid. + Netinkama reikšmė. + + + This value is not a valid time. + Ši reikšmė nėra laikas. + + + This value is not a valid URL. + Ši reikšmė nėra tinkamas interneto adresas. + + + The two values should be equal. + Abi reikšmės turi būti identiškos. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Byla yra per didelė. Maksimalus dydis yra {{ limit }} {{ suffix }}. + + + The file is too large. + Byla per didelė. + + + The file could not be uploaded. + Byla negali būti įkelta. + + + This value should be a valid number. + Ši reikšmė turi būti skaičius. + + + This value is not a valid country. + Ši reikšmė nėra tinkama šalis. + + + This file is not a valid image. + Byla nėra paveikslėlis. + + + This is not a valid IP address. + Ši reikšmė nėra tinkamas IP adresas. + + + This value is not a valid language. + Ši reikšmė nėra tinkama kalba. + + + This value is not a valid locale. + Ši reikšmė nėra tinkama lokalė. + + + This value is already used. + Ši reikšmė jau yra naudojama. + + + The size of the image could not be detected. + Nepavyko nustatyti nuotraukos dydžio. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Nuotraukos plotis per didelis ({{ width }}px). Maksimalus leidžiamas plotis yra {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Nuotraukos plotis per mažas ({{ width }}px). Minimalus leidžiamas plotis yra {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Nuotraukos aukštis per didelis ({{ height }}px). Maksimalus leidžiamas aukštis yra {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Nuotraukos aukštis per mažas ({{ height }}px). Minimalus leidžiamas aukštis yra {{ min_height }}px. + + + This value should be the user's current password. + Ši reikšmė turi sutapti su dabartiniu naudotojo slaptažodžiu. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ši reikšmė turi turėti lygiai {{ limit }} simbolį.|Ši reikšmė turi turėti lygiai {{ limit }} simbolius.|Ši reikšmė turi turėti lygiai {{ limit }} simbolių. + + + The file was only partially uploaded. + Failas buvo tik dalinai įkeltas. + + + No file was uploaded. + Nebuvo įkelta jokių failų. + + + No temporary folder was configured in php.ini. + Nėra sukonfiguruoto jokio laikino katalogo php.ini faile. + + + Cannot write temporary file to disk. + Nepavyko išsaugoti laikino failo. + + + A PHP extension caused the upload to fail. + PHP plėtinys sutrukdė failo įkėlimą ir jis nepavyko. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Sąraše turi būti {{ limit }} arba daugiau įrašų.|Sąraše turi būti {{ limit }} arba daugiau įrašų.|Sąraše turi būti {{ limit }} arba daugiau įrašų. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Sąraše turi būti {{ limit }} arba mažiau įrašų.|Sąraše turi būti {{ limit }} arba mažiau įrašų.|Sąraše turi būti {{ limit }} arba mažiau įrašų. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Sąraše turi būti lygiai {{ limit }} įrašas.|Sąraše turi būti lygiai {{ limit }} įrašai.|Sąraše turi būti lygiai {{ limit }} įrašų. + + + Invalid card number. + Klaidingas kortelės numeris. + + + Unsupported card type or invalid card number. + Kortelės tipas nepalaikomas arba klaidingas kortelės numeris. + + + This is not a valid International Bank Account Number (IBAN). + Ši reišmė neatitinka tarptautinio banko sąskaitos numerio formato (IBAN). + + + This value is not a valid ISBN-10. + Ši reikšmė neatitinka ISBN-10 formato. + + + This value is not a valid ISBN-13. + Ši reikšmė neatitinka ISBN-13 formato. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ši reikšmė neatitinka nei ISBN-10, nei ISBN-13 formato. + + + This value is not a valid ISSN. + Ši reišmė neatitinka ISSN formato. + + + This value is not a valid currency. + Netinkamas valiutos formatas. + + + This value should be equal to {{ compared_value }}. + Ši reikšmė turi būti lygi {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ši reikšmė turi būti didesnė už {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ši reikšmė turi būti didesnė už arba lygi {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ši reikšmė turi būti identiška {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ši reikšmė turi būti mažesnė už {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ši reikšmė turi būti mažesnė už arba lygi {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ši reikšmė neturi būti lygi {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ši reikšmė neturi būti identiška {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Nuotraukos santykis yra per didelis ({{ ratio }}). Didžiausias leistinas santykis yra {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Nuotraukos santykis yra per mažas ({{ ratio }}). Mažiausias leistinas santykis yra {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Nuotrauka yra kvadratinė ({{ width }}x{{ height }}px). Kvadratinės nuotraukos nėra leistinos. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Nuotrauka orientuota į plotį ({{ width }}x{{ height }}px). Nuotraukos orientuotos į plotį nėra leistinos. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Nuotrauka orientuota į aukštį ({{ width }}x{{ height }}px). Nuotraukos orientuotos į aukštį nėra leistinos. + + + An empty file is not allowed. + Failas negali būti tuščias. + + + + 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 @@ + + + + + + This value should be false. + Энэ утга буруу байх ёстой. + + + This value should be true. + Энэ утга үнэн байх ёстой. + + + This value should be of type {{ type }}. + Энэ утга {{ type }} -н төрөл байх ёстой. + + + This value should be blank. + Энэ утга хоосон байх ёстой. + + + The value you selected is not a valid choice. + Сонгосон утга буруу байна. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Хамгийн багадаа {{ limit }} утга сонгогдсон байх ёстой. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Хамгийн ихдээ {{ limit }} утга сонгогдох боломжтой. + + + One or more of the given values is invalid. + Өгөгдсөн нэг эсвэл нэгээс олон утга буруу байна. + + + This field was not expected. + Энэ талбар нь хүлээгдэж байсан юм. + + + This field is missing. + Энэ талбар нь алга болсон байна. + + + This value is not a valid date. + Энэ утга буруу date төрөл байна . + + + This value is not a valid datetime. + Энэ утга буруу цаг төрөл байна. + + + This value is not a valid email address. + И-майл хаяг буруу байна. + + + The file could not be found. + Файл олдсонгүй. + + + The file is not readable. + Файл уншигдахуйц биш байна. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файл хэтэрхий том байна ({{ size }} {{ suffix }}). Зөвшөөрөгдөх дээд хэмжээ {{ limit }} {{ suffix }} байна. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Файлын MIME-төрөл нь буруу байна ({{ type }}). Зөвшөөрөгдөх MIME-төрлүүд {{ types }}. + + + This value should be {{ limit }} or less. + Энэ утга {{ limit }} юмуу эсвэл бага байна. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Энэ утга хэтэрхий урт байна. {{ limit }} тэмдэгтийн урттай юмуу эсвэл бага байна. + + + This value should be {{ limit }} or more. + Энэ утга {{ limit }} юмуу эсвэл их байна. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Энэ утга хэтэрхий богино байна. {{ limit }} тэмдэгт эсвэл их байна. + + + This value should not be blank. + Энэ утга хоосон байж болохгүй. + + + This value should not be null. + Энэ утга null байж болохгүй. + + + This value should be null. + Энэ утга null байна. + + + This value is not valid. + Энэ утга буруу байна. + + + This value is not a valid time. + Энэ утга буруу цаг төрөл байна. + + + This value is not a valid URL. + Энэ утга буруу URL байна . + + + The two values should be equal. + Хоёр утгууд ижил байх ёстой. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файл хэтэрхий том байна. Зөвшөөрөгдөх дээд хэмжээ нь {{ limit }} {{ suffix }} байна. + + + The file is too large. + Файл хэтэрхий том байна. + + + The file could not be uploaded. + Файл upload хийгдсэнгүй. + + + This value should be a valid number. + Энэ утга зөвхөн тоо байна. + + + This value is not a valid country. + Энэ утга үнэн бодит улс биш байна. + + + This file is not a valid image. + Файл зураг биш байна. + + + This is not a valid IP address. + IP хаяг зөв биш байна. + + + This value is not a valid language. + Энэ утга үнэн зөв хэл биш байна . + + + + 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 @@ + + + + + + This value should be false. + Verdien skal være falsk. + + + This value should be true. + Verdien skal være sann. + + + This value should be of type {{ type }}. + Verdien skal være av typen {{ type }}. + + + This value should be blank. + Verdien skal være blank. + + + The value you selected is not a valid choice. + Verdien skal være en av de gitte valg. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du skal velge minst {{ limit }} valg. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan maks velge {{ limit }} valg. + + + One or more of the given values is invalid. + En eller flere av de oppgitte verdier er ugyldige. + + + This field was not expected. + Dette feltet ikke var forventet. + + + This field is missing. + Dette feltet mangler. + + + This value is not a valid date. + Verdien er ikke en gyldig dato. + + + This value is not a valid datetime. + Verdien er ikke en gyldig dato og tid. + + + This value is not a valid email address. + Verdien er ikke en gyldig e-mail adresse. + + + The file could not be found. + Filen kunne ikke finnes. + + + The file is not readable. + Filen kan ikke leses. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor ({{ size }} {{ suffix }}). Tilatte maksimale størrelse {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mimetypen av filen er ugyldig ({{ type }}). Tilatte mimetyper er {{ types }}. + + + This value should be {{ limit }} or less. + Verdien skal være {{ limit }} eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Verdien er for lang. Den skal ha {{ limit }} bokstaver eller mindre. + + + This value should be {{ limit }} or more. + Verdien skal være {{ limit }} eller mer. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Verdien er for kort. Den skal ha {{ limit }} tegn eller flere. + + + This value should not be blank. + Verdien må ikke være blank. + + + This value should not be null. + Verdien må ikke være tom (null). + + + This value should be null. + Verdien skal være tom (null). + + + This value is not valid. + Verdien er ikke gyldig. + + + This value is not a valid time. + Verdien er ikke en gyldig tid. + + + This value is not a valid URL. + Verdien er ikke en gyldig URL. + + + The two values should be equal. + De to verdier skal være ens. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor. Den maksimale størrelse er {{ limit }} {{ suffix }}. + + + The file is too large. + Filen er for stor. + + + The file could not be uploaded. + Filen kunne ikke lastes opp. + + + This value should be a valid number. + Denne verdi skal være et gyldig tall. + + + This file is not a valid image. + Denne filen er ikke et gyldig bilde. + + + This is not a valid IP address. + Dette er ikke en gyldig IP adresse. + + + This value is not a valid language. + Denne verdi er ikke et gyldig språk. + + + This value is not a valid locale. + Denne verdi er ikke en gyldig lokalitet. + + + This value is not a valid country. + Denne verdi er ikke et gyldig land. + + + + 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 @@ + + + + + + This value should be false. + Deze waarde mag niet waar zijn. + + + This value should be true. + Deze waarde moet waar zijn. + + + This value should be of type {{ type }}. + Deze waarde moet van het type {{ type }} zijn. + + + This value should be blank. + Deze waarde moet leeg zijn. + + + The value you selected is not a valid choice. + De geselecteerde waarde is geen geldige optie. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Selecteer ten minste {{ limit }} optie.|Selecteer ten minste {{ limit }} opties. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Selecteer maximaal {{ limit }} optie.|Selecteer maximaal {{ limit }} opties. + + + One or more of the given values is invalid. + Eén of meer van de ingegeven waarden zijn ongeldig. + + + This field was not expected. + Dit veld was niet verwacht. + + + This field is missing. + Dit veld ontbreekt. + + + This value is not a valid date. + Deze waarde is geen geldige datum. + + + This value is not a valid datetime. + Deze waarde is geen geldige datum en tijd. + + + This value is not a valid email address. + Deze waarde is geen geldig e-mailadres. + + + The file could not be found. + Het bestand is niet gevonden. + + + The file is not readable. + Het bestand is niet leesbaar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Het bestand is te groot ({{ size }} {{ suffix }}). Toegestane maximum grootte is {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Het mime type van het bestand is ongeldig ({{ type }}). Toegestane mime types zijn {{ types }}. + + + This value should be {{ limit }} or less. + Deze waarde moet {{ limit }} of minder zijn. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Deze waarde is te lang. Hij mag maximaal {{ limit }} teken bevatten.|Deze waarde is te lang. Hij mag maximaal {{ limit }} tekens bevatten. + + + This value should be {{ limit }} or more. + Deze waarde moet {{ limit }} of meer zijn. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Deze waarde is te kort. Hij moet tenminste {{ limit }} teken bevatten.|Deze waarde is te kort. Hij moet tenminste {{ limit }} tekens bevatten. + + + This value should not be blank. + Deze waarde mag niet leeg zijn. + + + This value should not be null. + Deze waarde mag niet null zijn. + + + This value should be null. + Deze waarde moet null zijn. + + + This value is not valid. + Deze waarde is ongeldig. + + + This value is not a valid time. + Deze waarde is geen geldige tijd. + + + This value is not a valid URL. + Deze waarde is geen geldige URL. + + + The two values should be equal. + De twee waarden moeten gelijk zijn. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Het bestand is te groot. Toegestane maximum grootte is {{ limit }} {{ suffix }}. + + + The file is too large. + Het bestand is te groot. + + + The file could not be uploaded. + Het bestand kon niet geüpload worden. + + + This value should be a valid number. + Deze waarde moet een geldig getal zijn. + + + This file is not a valid image. + Dit bestand is geen geldige afbeelding. + + + This is not a valid IP address. + Dit is geen geldig IP-adres. + + + This value is not a valid language. + Deze waarde representeert geen geldige taal. + + + This value is not a valid locale. + Deze waarde representeert geen geldige lokalisering. + + + This value is not a valid country. + Deze waarde representeert geen geldig land. + + + This value is already used. + Deze waarde wordt al gebruikt. + + + The size of the image could not be detected. + De grootte van de afbeelding kon niet bepaald worden. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + De afbeelding is te breed ({{ width }}px). De maximaal toegestane breedte is {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + De afbeelding is niet breed genoeg ({{ width }}px). De minimaal verwachte breedte is {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + De afbeelding is te hoog ({{ height }}px). De maximaal toegestane hoogte is {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + De afbeelding is niet hoog genoeg ({{ height }}px). De minimaal verwachte hoogte is {{ min_height }}px. + + + This value should be the user's current password. + Deze waarde moet het huidige wachtwoord van de gebruiker zijn. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Deze waarde moet exact {{ limit }} teken lang zijn.|Deze waarde moet exact {{ limit }} tekens lang zijn. + + + The file was only partially uploaded. + Het bestand is niet geheel geüpload. + + + No file was uploaded. + Er is geen bestand geüpload. + + + No temporary folder was configured in php.ini. + Er is geen tijdelijke map geconfigureerd in php.ini. + + + Cannot write temporary file to disk. + Kan het tijdelijke bestand niet wegschrijven op disk. + + + A PHP extension caused the upload to fail. + De upload is mislukt vanwege een PHP-extensie. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Deze collectie moet {{ limit }} element of meer bevatten.|Deze collectie moet {{ limit }} elementen of meer bevatten. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Deze collectie moet {{ limit }} element of minder bevatten.|Deze collectie moet {{ limit }} elementen of minder bevatten. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Deze collectie moet exact {{ limit }} element bevatten.|Deze collectie moet exact {{ limit }} elementen bevatten. + + + Invalid card number. + Ongeldig creditcardnummer. + + + Unsupported card type or invalid card number. + Niet-ondersteund type creditcard of ongeldig nummer. + + + This is not a valid International Bank Account Number (IBAN). + Dit is geen geldig internationaal bankrekeningnummer (IBAN). + + + This value is not a valid ISBN-10. + Deze waarde is geen geldige ISBN-10. + + + This value is not a valid ISBN-13. + Deze waarde is geen geldige ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Deze waarde is geen geldige ISBN-10 of ISBN-13 waarde. + + + This value is not a valid ISSN. + Deze waarde is geen geldige ISSN waarde. + + + This value is not a valid currency. + Deze waarde is geen geldige valuta. + + + This value should be equal to {{ compared_value }}. + Deze waarde moet gelijk zijn aan {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Deze waarde moet groter zijn dan {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Deze waarde moet groter dan of gelijk aan {{ compared_value }} zijn. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Deze waarde moet identiek zijn aan {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Deze waarde moet minder zijn dan {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Deze waarde moet minder dan of gelijk aan {{ compared_value }} zijn. + + + This value should not be equal to {{ compared_value }}. + Deze waarde mag niet gelijk zijn aan {{ compared_value }}. + + + This value should not be identical to {{ compared_value }}. + Deze waarde mag niet identiek zijn aan {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + De afbeeldingsverhouding is te groot ({{ ratio }}). Maximale verhouding is {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + De afbeeldingsverhouding is te klein ({{ ratio }}). Minimale verhouding is {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + De afbeelding is vierkant ({{ width }}x{{ height }}px). Vierkante afbeeldingen zijn niet toegestaan. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + De afbeelding is liggend ({{ width }}x{{ height }}px). Liggende afbeeldingen zijn niet toegestaan. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + De afbeelding is staand ({{ width }}x{{ height }}px). Staande afbeeldingen zijn niet toegestaan. + + + An empty file is not allowed. + Lege bestanden zijn niet toegestaan. + + + This value does not match the expected {{ charset }} charset. + Deze waarde is niet in de verwachte tekencodering {{ charset }}. + + + + 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 @@ + + + + + + This value should be false. + Verdien skulle ha vore tom/nei. + + + This value should be true. + Verdien skulla ha vore satt/ja. + + + This value should be of type {{ type }}. + Verdien må vere av typen {{ type }}. + + + This value should be blank. + Verdien skal vere blank. + + + The value you selected is not a valid choice. + Verdien du valgte er ikkje gyldig. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du må velge minst {{ limit }} valg. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan maksimalt gjere {{ limit }} valg. + + + One or more of the given values is invalid. + Ein eller fleire av dei opplyste verdiane er ugyldige. + + + This field was not expected. + Dette feltet var ikke forventet. + + + This field is missing. + Dette feltet mangler. + + + This value is not a valid date. + Verdien er ikkje ein gyldig dato. + + + This value is not a valid datetime. + Verdien er ikkje ein gyldig dato og tid. + + + This value is not a valid email address. + Verdien er ikkje ei gyldig e-postadresse. + + + The file could not be found. + Fila kunne ikkje finnes. + + + The file is not readable. + Fila kan ikkje lesast. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fila er for stor ({{ size }} {{ suffix }}). Tillatt maksimal størrelse er {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime-typen av fila er ugyldig ({{ type }}). Tillatte mime-typar er {{ types }}. + + + This value should be {{ limit }} or less. + Verdien må vere {{ limit }} eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Verdien er for lang. Den må vere {{ limit }} bokstavar eller mindre. + + + This value should be {{ limit }} or more. + Verdien må vere {{ limit }} eller meir. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Verdien er for kort. Den må ha {{ limit }} teikn eller fleire. + + + This value should not be blank. + Verdien må ikkje vere blank. + + + This value should not be null. + Verdien må ikkje vere tom (null). + + + This value should be null. + Verdien må vere tom (null). + + + This value is not valid. + Verdien er ikkje gyldig. + + + This value is not a valid time. + Verdien er ikkje gyldig tidseining. + + + This value is not a valid URL. + Verdien er ikkje ein gyldig URL. + + + The two values should be equal. + Dei to verdiane må vere like. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fila er for stor. Den maksimale storleik er {{ limit }} {{ suffix }}. + + + The file is too large. + Fila er for stor. + + + The file could not be uploaded. + Fila kunne ikkje bli lasta opp. + + + This value should be a valid number. + Verdien må vere eit gyldig tal. + + + This file is not a valid image. + Fila er ikkje eit gyldig bilete. + + + This is not a valid IP address. + Dette er ikkje ei gyldig IP-adresse. + + + This value is not a valid language. + Verdien er ikkje eit gyldig språk. + + + This value is not a valid locale. + Verdien er ikkje ein gyldig lokalitet (språk/region). + + + This value is not a valid country. + Verdien er ikkje eit gyldig land. + + + This value is already used. + Verdien er allereie i bruk. + + + The size of the image could not be detected. + Storleiken på biletet kunne ikkje oppdagast. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Biletbreidda er for stor, ({{ width }} pikslar). Tillatt maksimumsbreidde er {{ max_width }} pikslar. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Biletbreidda er for liten, ({{ width }} pikslar). Forventa minimumsbreidde er {{ min_width }} pikslar. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Bilethøgda er for stor, ({{ height }} pikslar). Tillatt maksimumshøgde er {{ max_height }} pikslar. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Billethøgda er for låg, ({{ height }} pikslar). Forventa minimumshøgde er {{ min_height }} pikslar. + + + This value should be the user's current password. + Verdien må vere brukaren sitt noverande passord. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Verdien må vere nøyaktig {{ limit }} teikn. + + + The file was only partially uploaded. + Fila vart kun delvis opplasta. + + + No file was uploaded. + Inga fil vart lasta opp. + + + No temporary folder was configured in php.ini. + Førebels mappe (tmp) er ikkje konfigurert i php.ini. + + + Cannot write temporary file to disk. + Kan ikkje skrive førebels fil til disk. + + + A PHP extension caused the upload to fail. + Ei PHP-udviding forårsaka feil under opplasting. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Denne samlinga må innehalde {{ limit }} element eller meir.|Denne samlinga må innehalde {{ limit }} element eller meir. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Denne samlinga må innehalde {{ limit }} element eller færre.|Denne samlinga må innehalde {{ limit }} element eller færre. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Denne samlinga må innehalde nøyaktig {{ limit }} element.|Denne samlinga må innehalde nøyaktig {{ limit }} element. + + + Invalid card number. + Ugyldig kortnummer. + + + Unsupported card type or invalid card number. + Korttypen er ikkje støtta eller ugyldig kortnummer. + + + + 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 @@ + + + + + + This value should be false. + Ta wartość powinna być fałszem. + + + This value should be true. + Ta wartość powinna być prawdą. + + + This value should be of type {{ type }}. + Ta wartość powinna być typu {{ type }}. + + + This value should be blank. + Ta wartość powinna być pusta. + + + The value you selected is not a valid choice. + Ta wartość powinna być jedną z podanych opcji. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Powinieneś wybrać co najmniej {{ limit }} opcję.|Powinieneś wybrać co najmniej {{ limit }} opcje.|Powinieneś wybrać co najmniej {{ limit }} opcji. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Powinieneś wybrać maksymalnie {{ limit }} opcję.|Powinieneś wybrać maksymalnie {{ limit }} opcje.|Powinieneś wybrać maksymalnie {{ limit }} opcji. + + + One or more of the given values is invalid. + Jedna lub więcej z podanych wartości jest nieprawidłowa. + + + This field was not expected. + To pole nie spodziewano. + + + This field is missing. + To pole jest chybianie. + + + This value is not a valid date. + Ta wartość nie jest prawidłową datą. + + + This value is not a valid datetime. + Ta wartość nie jest prawidłową datą i czasem. + + + This value is not a valid email address. + Ta wartość nie jest prawidłowym adresem email. + + + The file could not be found. + Plik nie mógł zostać odnaleziony. + + + The file is not readable. + Nie można odczytać pliku. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Plik jest za duży ({{ size }} {{ suffix }}). Maksymalny dozwolony rozmiar to {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Nieprawidłowy typ mime pliku ({{ type }}). Dozwolone typy mime to {{ types }}. + + + This value should be {{ limit }} or less. + Ta wartość powinna wynosić {{ limit }} lub mniej. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ta wartość jest zbyt długa. Powinna mieć {{ limit }} lub mniej znaków.|Ta wartość jest zbyt długa. Powinna mieć {{ limit }} lub mniej znaków.|Ta wartość jest zbyt długa. Powinna mieć {{ limit }} lub mniej znaków. + + + This value should be {{ limit }} or more. + Ta wartość powinna wynosić {{ limit }} lub więcej. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ta wartość jest zbyt krótka. Powinna mieć {{ limit }} lub więcej znaków.|Ta wartość jest zbyt krótka. Powinna mieć {{ limit }} lub więcej znaków.|Ta wartość jest zbyt krótka. Powinna mieć {{ limit }} lub więcej znaków. + + + This value should not be blank. + Ta wartość nie powinna być pusta. + + + This value should not be null. + Ta wartość nie powinna być nullem. + + + This value should be null. + Ta wartość powinna być nullem. + + + This value is not valid. + Ta wartość jest nieprawidłowa. + + + This value is not a valid time. + Ta wartość nie jest prawidłowym czasem. + + + This value is not a valid URL. + Ta wartość nie jest prawidłowym adresem URL. + + + The two values should be equal. + Obie wartości powinny być równe. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Plik jest za duży. Maksymalny dozwolony rozmiar to {{ limit }} {{ suffix }}. + + + The file is too large. + Plik jest za duży. + + + The file could not be uploaded. + Plik nie mógł być wgrany. + + + This value should be a valid number. + Ta wartość powinna być prawidłową liczbą. + + + This file is not a valid image. + Ten plik nie jest obrazem. + + + This is not a valid IP address. + To nie jest prawidłowy adres IP. + + + This value is not a valid language. + Ta wartość nie jest prawidłowym językiem. + + + This value is not a valid locale. + Ta wartość nie jest prawidłową lokalizacją. + + + This value is not a valid country. + Ta wartość nie jest prawidłową nazwą kraju. + + + This value is already used. + Ta wartość jest już wykorzystywana. + + + The size of the image could not be detected. + Nie można wykryć rozmiaru obrazka. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Szerokość obrazka jest zbyt duża ({{ width }}px). Maksymalna dopuszczalna szerokość to {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Szerokość obrazka jest zbyt mała ({{ width }}px). Oczekiwana minimalna szerokość to {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Wysokość obrazka jest zbyt duża ({{ height }}px). Maksymalna dopuszczalna wysokość to {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Wysokość obrazka jest zbyt mała ({{ height }}px). Oczekiwana minimalna wysokość to {{ min_height }}px. + + + This value should be the user's current password. + Ta wartość powinna być aktualnym hasłem użytkownika. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ta wartość powinna mieć dokładnie {{ limit }} znak.|Ta wartość powinna mieć dokładnie {{ limit }} znaki.|Ta wartość powinna mieć dokładnie {{ limit }} znaków. + + + The file was only partially uploaded. + Plik został wgrany tylko częściowo. + + + No file was uploaded. + Żaden plik nie został wgrany. + + + No temporary folder was configured in php.ini. + Nie skonfigurowano folderu tymczasowego w php.ini. + + + Cannot write temporary file to disk. + Nie można zapisać pliku tymczasowego na dysku. + + + A PHP extension caused the upload to fail. + Rozszerzenie PHP spowodowało błąd podczas wgrywania. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ten zbiór powinien zawierać {{ limit }} lub więcej elementów. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ten zbiór powinien zawierać {{ limit }} lub mniej elementów. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ten zbiór powinien zawierać dokładnie {{ limit }} element.|Ten zbiór powinien zawierać dokładnie {{ limit }} elementy.|Ten zbiór powinien zawierać dokładnie {{ limit }} elementów. + + + Invalid card number. + Nieprawidłowy numer karty. + + + Unsupported card type or invalid card number. + Nieobsługiwany rodzaj karty lub nieprawidłowy numer karty. + + + This is not a valid International Bank Account Number (IBAN). + Nieprawidłowy międzynarodowy numer rachunku bankowego (IBAN). + + + This value is not a valid ISBN-10. + Ta wartość nie jest prawidłowym numerem ISBN-10. + + + This value is not a valid ISBN-13. + Ta wartość nie jest prawidłowym numerem ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ta wartość nie jest prawidłowym numerem ISBN-10 ani ISBN-13. + + + This value is not a valid ISSN. + Ta wartość nie jest prawidłowym numerem ISSN. + + + This value is not a valid currency. + Ta wartość nie jest prawidłową walutą. + + + This value should be equal to {{ compared_value }}. + Ta wartość powinna być równa {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ta wartość powinna być większa niż {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ta wartość powinna być większa bądź równa {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ta wartość powinna być identycznego typu {{ compared_value_type }} oraz wartości {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ta wartość powinna być mniejsza niż {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ta wartość powinna być mniejsza bądź równa {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ta wartość nie powinna być równa {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ta wartość nie powinna być identycznego typu {{ compared_value_type }} oraz wartości {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Proporcje obrazu są zbyt duże ({{ ratio }}). Maksymalne proporcje to {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Proporcje obrazu są zbyt małe ({{ ratio }}). Minimalne proporcje to {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Obraz jest kwadratem ({{ width }}x{{ height }}px). Kwadratowe obrazy nie są akceptowane. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Obraz jest panoramiczny ({{ width }}x{{ height }}px). Panoramiczne zdjęcia nie są akceptowane. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Obraz jest portretowy ({{ width }}x{{ height }}px). Portretowe zdjęcia nie są akceptowane. + + + An empty file is not allowed. + Plik nie może być pusty. + + + This value does not match the expected {{ charset }} charset. + Ta wartość nie pasuje do oczekiwanego zestawu znaków {{ charset }}. + + + + 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 @@ + + + + + + This value should be false. + Este valor deveria ser falso. + + + This value should be true. + Este valor deveria ser verdadeiro. + + + This value should be of type {{ type }}. + Este valor deveria ser do tipo {{ type }}. + + + This value should be blank. + Este valor deveria ser vazio. + + + The value you selected is not a valid choice. + O valor selecionado não é uma opção válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Você deveria selecionar {{ limit }} opção no mínimo.|Você deveria selecionar {{ limit }} opções no mínimo. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Você deve selecionar, no máximo {{ limit }} opção.|Você deve selecionar, no máximo {{ limit }} opções. + + + One or more of the given values is invalid. + Um ou mais dos valores introduzidos não são válidos. + + + This field was not expected. + Este campo não era esperado. + + + This field is missing. + Este campo está faltando. + + + This value is not a valid date. + Este valor não é uma data válida. + + + This value is not a valid datetime. + Este valor não é uma data-hora válida. + + + This value is not a valid email address. + Este valor não é um endereço de e-mail válido. + + + The file could not be found. + O arquivo não pôde ser encontrado. + + + The file is not readable. + O arquivo não pôde ser lido. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande ({{ size }} {{ suffix }}). O tamanho máximo permitido é de {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + O tipo mime do arquivo é inválido ({{ type }}). Os tipos mime permitidos são {{ types }}. + + + This value should be {{ limit }} or less. + Este valor deveria ser {{ limit }} ou menor. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + O valor é muito longo. Deveria ter {{ limit }} caracteres ou menos. + + + This value should be {{ limit }} or more. + Este valor deveria ser {{ limit }} ou mais. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + O valor é muito curto. Deveria de ter {{ limit }} caractere ou mais.|O valor é muito curto. Deveria de ter {{ limit }} caracteres ou mais. + + + This value should not be blank. + Este valor não deveria ser branco/vazio. + + + This value should not be null. + Este valor não deveria ser nulo. + + + This value should be null. + Este valor deveria ser nulo. + + + This value is not valid. + Este valor não é válido. + + + This value is not a valid time. + Este valor não é uma hora válida. + + + This value is not a valid URL. + Este valor não é um URL válido. + + + The two values should be equal. + Os dois valores deveriam ser iguais. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande. O tamanho máximo permitido é de {{ limit }} {{ suffix }}. + + + The file is too large. + O ficheiro é muito grande. + + + The file could not be uploaded. + Não foi possível carregar o ficheiro. + + + This value should be a valid number. + Este valor deveria de ser um número válido. + + + This file is not a valid image. + Este ficheiro não é uma imagem. + + + This is not a valid IP address. + Este endereço de IP não é válido. + + + This value is not a valid language. + Este valor não é uma linguagem válida. + + + This value is not a valid locale. + Este valor não é um 'locale' válido. + + + This value is not a valid country. + Este valor não é um País válido. + + + This value is already used. + Este valor já está a ser usado. + + + The size of the image could not be detected. + O tamanho da imagem não foi detetado. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura da imagem ({{ width }}px) é muito grande. A largura máxima da imagem é: {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura da imagem ({{ width }}px) é muito pequena. A largura miníma da imagem é de: {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura da imagem ({{ height }}px) é muito grande. A altura máxima da imagem é de: {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura da imagem ({{ height }}px) é muito pequena. A altura miníma da imagem é de: {{ min_height }}px. + + + This value should be the user's current password. + Este valor deveria de ser a password atual do utilizador. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor tem de ter exatamente {{ limit }} carateres. + + + The file was only partially uploaded. + Só foi enviado parte do ficheiro. + + + No file was uploaded. + Nenhum ficheiro foi enviado. + + + No temporary folder was configured in php.ini. + Não existe nenhum directório temporária configurado no ficheiro php.ini. + + + Cannot write temporary file to disk. + Não foi possível escrever ficheiros temporários no disco. + + + A PHP extension caused the upload to fail. + Uma extensão PHP causou a falha no envio. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta coleção deve conter {{ limit }} elemento ou mais.|Esta coleção deve conter {{ limit }} elementos ou mais. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta coleção deve conter {{ limit }} elemento ou menos.|Esta coleção deve conter {{ limit }} elementos ou menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta coleção deve conter exatamente {{ limit }} elemento.|Esta coleção deve conter exatamente {{ limit }} elementos. + + + Invalid card number. + Número de cartão inválido. + + + Unsupported card type or invalid card number. + Tipo de cartão não suportado ou número de cartão inválido. + + + This is not a valid International Bank Account Number (IBAN). + Este não é um Número Internacional de Conta Bancária (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor não é um ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor não é um ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor não é um ISBN-10 ou ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor não é um ISSN válido. + + + This value is not a valid currency. + Este não é um valor monetário válido. + + + This value should be equal to {{ compared_value }}. + Este valor deve ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor deve ser superior a {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor deve ser igual ou superior a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor deve ser inferior a {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor deve ser igual ou inferior a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor não deve ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor não deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + O formato da imagem é muito grande ({{ ratio }}). O formato máximo é {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + O formato da imagem é muito pequeno ({{ ratio }}). O formato mínimo esperado é {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A imagem é um quadrado ({{ width }}x{{ height }}px). Imagens quadradas não são permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A imagem está orientada à paisagem ({{ width }}x{{ height }}px). Imagens orientadas à paisagem não são permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A imagem está orientada ao retrato ({{ width }}x{{ height }}px). Imagens orientadas ao retrato não são permitidas. + + + An empty file is not allowed. + Ficheiro vazio não é permitido. + + + + 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 @@ + + + + + + This value should be false. + Este valor deve ser falso. + + + This value should be true. + Este valor deve ser verdadeiro. + + + This value should be of type {{ type }}. + Este valor deve ser do tipo {{ type }}. + + + This value should be blank. + Este valor deve ser vazio. + + + The value you selected is not a valid choice. + O valor selecionado não é uma opção válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Você deve selecionar, no mínimo, {{ limit }} opção.|Você deve selecionar, no mínimo, {{ limit }} opções. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Você deve selecionar, no máximo, {{ limit }} opção.|Você deve selecionar, no máximo, {{ limit }} opções. + + + One or more of the given values is invalid. + Um ou mais valores informados são inválidos. + + + This field was not expected. + Este campo não era esperado. + + + This field is missing. + Este campo está ausente. + + + This value is not a valid date. + Este valor não é uma data válida. + + + This value is not a valid datetime. + Este valor não é uma data e hora válida. + + + This value is not a valid email address. + Este valor não é um endereço de e-mail válido. + + + The file could not be found. + O arquivo não foi encontrado. + + + The file is not readable. + O arquivo não pode ser lido. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande ({{ size }} {{ suffix }}). O tamanho máximo permitido é {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + O tipo mime do arquivo é inválido ({{ type }}). Os tipos mime permitidos são {{ types }}. + + + This value should be {{ limit }} or less. + Este valor deve ser {{ limit }} ou menos. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Este valor é muito longo. Deve ter {{ limit }} caractere ou menos.|Este valor é muito longo. Deve ter {{ limit }} caracteres ou menos. + + + This value should be {{ limit }} or more. + Este valor deve ser {{ limit }} ou mais. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Este valor é muito curto. Deve ter {{ limit }} caractere ou mais.|Este valor é muito curto. Deve ter {{ limit }} caracteres ou mais. + + + This value should not be blank. + Este valor não deve ser vazio. + + + This value should not be null. + Este valor não deve ser nulo. + + + This value should be null. + Este valor deve ser nulo. + + + This value is not valid. + Este valor não é válido. + + + This value is not a valid time. + Este valor não é uma hora válida. + + + This value is not a valid URL. + Este valor não é uma URL válida. + + + The two values should be equal. + Os dois valores devem ser iguais. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande. O tamanho máximo permitido é de {{ limit }} {{ suffix }}. + + + The file is too large. + O arquivo é muito grande. + + + The file could not be uploaded. + O arquivo não pode ser enviado. + + + This value should be a valid number. + Este valor deve ser um número válido. + + + This file is not a valid image. + Este arquivo não é uma imagem válida. + + + This is not a valid IP address. + Este não é um endereço de IP válido. + + + This value is not a valid language. + Este valor não é um idioma válido. + + + This value is not a valid locale. + Este valor não é uma localidade válida. + + + This value is not a valid country. + Este valor não é um país válido. + + + This value is already used. + Este valor já está sendo usado. + + + The size of the image could not be detected. + O tamanho da imagem não pode ser detectado. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura da imagem é muito grande ({{ width }}px). A largura máxima permitida é de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura da imagem é muito pequena ({{ width }}px). A largura mínima esperada é de {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura da imagem é muito grande ({{ height }}px). A altura máxima permitida é de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura da imagem é muito pequena ({{ height }}px). A altura mínima esperada é de {{ min_height }}px. + + + This value should be the user's current password. + Este valor deve ser a senha atual do usuário. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor deve ter exatamente {{ limit }} caractere.|Este valor deve ter exatamente {{ limit }} caracteres. + + + The file was only partially uploaded. + O arquivo foi enviado apenas parcialmente. + + + No file was uploaded. + Nenhum arquivo foi enviado. + + + No temporary folder was configured in php.ini. + Nenhum diretório temporário foi configurado no php.ini. + + + Cannot write temporary file to disk. + Não foi possível escrever o arquivo temporário no disco. + + + A PHP extension caused the upload to fail. + Uma extensão PHP fez com que o envio falhasse. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta coleção deve conter {{ limit }} elemento ou mais.|Esta coleção deve conter {{ limit }} elementos ou mais. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta coleção deve conter {{ limit }} elemento ou menos.|Esta coleção deve conter {{ limit }} elementos ou menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta coleção deve conter exatamente {{ limit }} elemento.|Esta coleção deve conter exatamente {{ limit }} elementos. + + + Invalid card number. + Número de cartão inválido. + + + Unsupported card type or invalid card number. + Tipo de cartão não suportado ou número de cartão inválido. + + + This is not a valid International Bank Account Number (IBAN). + Este não é um Número Internacional de Conta Bancária (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor não é um ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor não é um ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor não é um ISBN-10 e nem um ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor não é um ISSN válido. + + + This value is not a valid currency. + Este não é um valor monetário válido. + + + This value should be equal to {{ compared_value }}. + Este valor deve ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor deve ser maior que {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor deve ser maior ou igual a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor deve ser menor que {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor deve ser menor ou igual a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor não deve ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor não deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A proporção da imagem é muito grande ({{ ratio }}). A proporção máxima permitida é {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A proporção da imagem é muito pequena ({{ ratio }}). A proporção mínima esperada é {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A imagem está num formato quadrado ({{ width }}x{{ height }}px). Imagens com formato quadrado não são permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A imagem está orientada à paisagem ({{ width }}x{{ height }}px). Imagens orientadas à paisagem não são permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A imagem está orientada ao retrato ({{ width }}x{{ height }}px). Imagens orientadas ao retrato não são permitidas. + + + An empty file is not allowed. + Arquivo vazio não é permitido. + + + The host could not be resolved. + O host não pôde ser resolvido. + + + This value does not match the expected {{ charset }} charset. + Este valor não corresponde ao charset {{ charset }} esperado. + + + + 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 @@ + + + + + + This value should be false. + Această valoare ar trebui să fie falsă (false). + + + This value should be true. + Această valoare ar trebui să fie adevărată (true). + + + This value should be of type {{ type }}. + Această valoare ar trebui să fie de tipul {{ type }}. + + + This value should be blank. + Această valoare ar trebui sa fie goală. + + + The value you selected is not a valid choice. + Valoarea selectată nu este o opțiune validă. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Trebuie să selectați cel puțin {{ limit }} opțiune.|Trebuie să selectați cel puțin {{ limit }} opțiuni.|Trebuie să selectați cel puțin {{ limit }} de opțiuni + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Trebuie să selectați cel mult {{ limit }} opțiune.|Trebuie să selectați cel mult {{ limit }} opțiuni.|Trebuie să selectați cel mult {{ limit }} de opțiuni. + + + One or more of the given values is invalid. + Una sau mai multe dintre valorile furnizate sunt invalide. + + + This field was not expected. + Acest câmp nu era de aşteptat. + + + This field is missing. + Acest câmp este lipsă. + + + This value is not a valid date. + Această valoare nu reprezintă o dată validă. + + + This value is not a valid datetime. + Această valoare nu reprezintă o dată și oră validă. + + + This value is not a valid email address. + Această valoare nu reprezintă o adresă de e-mail validă. + + + The file could not be found. + Fișierul nu a putut fi găsit. + + + The file is not readable. + Fișierul nu poate fi citit. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fișierul este prea mare ({{ size }} {{ suffix }}). Dimensiunea maximă permisă este {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Tipul fișierului este invalid ({{ type }}). Tipurile permise de fișiere sunt ({{ types }}). + + + This value should be {{ limit }} or less. + Această valoare ar trebui să fie cel mult {{ limit }}. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} caracter.|Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} caractere.|Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} de caractere. + + + This value should be {{ limit }} or more. + Această valoare ar trebui să fie cel puțin {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} caracter.|Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} caractere.|Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} de caractere. + + + This value should not be blank. + Această valoare nu ar trebui să fie goală. + + + This value should not be null. + Această valoare nu ar trebui să fie nulă (null). + + + This value should be null. + Această valoare ar trebui să fie nulă (null). + + + This value is not valid. + Această valoare nu este validă. + + + This value is not a valid time. + Această valoare nu reprezintă o oră validă. + + + This value is not a valid URL. + Această valoare nu reprezintă un URL (link) valid. + + + The two values should be equal. + Cele două valori ar trebui să fie egale. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fișierul este prea mare. Mărimea maximă permisă este {{ limit }} {{ suffix }}. + + + The file is too large. + Fișierul este prea mare. + + + The file could not be uploaded. + Fișierul nu a putut fi încărcat. + + + This value should be a valid number. + Această valoare nu reprezintă un număr valid. + + + This file is not a valid image. + Acest fișier nu este o imagine validă. + + + This is not a valid IP address. + Această valoare nu este o adresă IP validă. + + + This value is not a valid language. + Această valoare nu reprezintă o limbă corectă. + + + This value is not a valid locale. + Această valoare nu reprezintă un dialect (o limbă) corect. + + + This value is not a valid country. + Această valoare nu este o țară validă. + + + This value is already used. + Această valoare este folosită deja. + + + The size of the image could not be detected. + Mărimea imaginii nu a putut fi detectată. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Lățimea imaginii este prea mare ({{ width }}px). Lățimea maximă permisă este de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Lățimea imaginii este prea mică ({{ width }}px). Lățimea minimă permisă este de {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Înălțimea imaginii este prea mare ({{ height }}px). Înălțimea maximă permisă este de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Înălțimea imaginii este prea mică ({{ height }}px). Înălțimea minimă permisă este de {{ min_height }}px. + + + This value should be the user's current password. + Această valoare trebuie să fie parola curentă a utilizatorului. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Această valoare trebuie să conțină exact {{ limit }} caracter.|Această valoare trebuie să conțină exact {{ limit }} caractere.|Această valoare trebuie să conțină exact {{ limit }} de caractere. + + + The file was only partially uploaded. + Fișierul a fost încărcat parțial. + + + No file was uploaded. + Nu a fost încărcat nici un fișier. + + + No temporary folder was configured in php.ini. + Nu este configurat nici un director temporar in php.ini. + + + Cannot write temporary file to disk. + Nu a fost posibilă scrierea fișierului temporar pe disk. + + + A PHP extension caused the upload to fail. + O extensie PHP a prevenit încărcarea cu succes a fișierului. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Această colecție trebuie să conțină cel puțin {{ limit }} element.|Această colecție trebuie să conțină cel puțin {{ limit }} elemente.|Această colecție trebuie să conțină cel puțin {{ limit }} de elemente. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Această colecție trebuie să conțină cel mult {{ limit }} element.|Această colecție trebuie să conțină cel mult {{ limit }} elemente.|Această colecție trebuie să conțină cel mult {{ limit }} de elemente. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + 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. + + + Invalid card number. + Numărul card invalid. + + + Unsupported card type or invalid card number. + Tipul sau numărul cardului nu sunt valide. + + + This is not a valid International Bank Account Number (IBAN). + Acesta nu este un cod IBAN (International Bank Account Number) valid. + + + This value is not a valid ISBN-10. + Această valoare nu este un cod ISBN-10 valid. + + + This value is not a valid ISBN-13. + Această valoare nu este un cod ISBN-13 valid. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Această valoare nu este un cod ISBN-10 sau ISBN-13 valid. + + + This value is not a valid ISSN. + Această valoare nu este un cod ISSN valid. + + + This value is not a valid currency. + Această valoare nu este o monedă validă. + + + This value should be equal to {{ compared_value }}. + Această valoare trebuie să fie egală cu {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Această valoare trebuie să fie mai mare de {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Această valoare trebuie să fie mai mare sau egală cu {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Această valoare trebuie identică cu {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Această valoare trebuie să fie mai mică de {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Această valoare trebuie să fie mai mică sau egală cu {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Această valoare nu trebuie să fie egală cu {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Această valoare nu trebuie să fie identică cu {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + Значение должно быть ложным. + + + This value should be true. + Значение должно быть истинным. + + + This value should be of type {{ type }}. + Тип значения должен быть {{ type }}. + + + This value should be blank. + Значение должно быть пустым. + + + The value you selected is not a valid choice. + Выбранное Вами значение недопустимо. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Вы должны выбрать хотя бы {{ limit }} вариант.|Вы должны выбрать хотя бы {{ limit }} варианта.|Вы должны выбрать хотя бы {{ limit }} вариантов. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Вы должны выбрать не более чем {{ limit }} вариант.|Вы должны выбрать не более чем {{ limit }} варианта.|Вы должны выбрать не более чем {{ limit }} вариантов. + + + One or more of the given values is invalid. + Одно или несколько заданных значений недопустимо. + + + This field was not expected. + Это поле не ожидалось. + + + This field is missing. + Это поле отсутствует. + + + This value is not a valid date. + Значение не является правильной датой. + + + This value is not a valid datetime. + Значение даты и времени недопустимо. + + + This value is not a valid email address. + Значение адреса электронной почты недопустимо. + + + The file could not be found. + Файл не может быть найден. + + + The file is not readable. + Файл не может быть прочитан. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файл слишком большой ({{ size }} {{ suffix }}). Максимально допустимый размер {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME-тип файла недопустим ({{ type }}). Допустимы MIME-типы файлов {{ types }}. + + + This value should be {{ limit }} or less. + Значение должно быть {{ limit }} или меньше. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Значение слишком длинное. Должно быть равно {{ limit }} символу или меньше.|Значение слишком длинное. Должно быть равно {{ limit }} символам или меньше.|Значение слишком длинное. Должно быть равно {{ limit }} символам или меньше. + + + This value should be {{ limit }} or more. + Значение должно быть {{ limit }} или больше. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Значение слишком короткое. Должно быть равно {{ limit }} символу или больше.|Значение слишком короткое. Должно быть равно {{ limit }} символам или больше.|Значение слишком короткое. Должно быть равно {{ limit }} символам или больше. + + + This value should not be blank. + Значение не должно быть пустым. + + + This value should not be null. + Значение не должно быть null. + + + This value should be null. + Значение должно быть null. + + + This value is not valid. + Значение недопустимо. + + + This value is not a valid time. + Значение времени недопустимо. + + + This value is not a valid URL. + Значение не является допустимым URL. + + + The two values should be equal. + Оба значения должны быть одинаковыми. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файл слишком большой. Максимально допустимый размер {{ limit }} {{ suffix }}. + + + The file is too large. + Файл слишком большой. + + + The file could not be uploaded. + Файл не может быть загружен. + + + This value should be a valid number. + Значение должно быть числом. + + + This value is not a valid country. + Значение не является допустимой страной. + + + This file is not a valid image. + Файл не является допустимым форматом изображения. + + + This is not a valid IP address. + Значение не является допустимым IP адресом. + + + This value is not a valid language. + Значение не является допустимым языком. + + + This value is not a valid locale. + Значение не является допустимой локалью. + + + This value is already used. + Это значение уже используется. + + + The size of the image could not be detected. + Не удалось определить размер изображения. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина изображения слишком велика ({{ width }}px). Максимально допустимая ширина {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина изображения слишком мала ({{ width }}px). Минимально допустимая ширина {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Высота изображения слишком велика ({{ height }}px). Максимально допустимая высота {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Высота изображения слишком мала ({{ height }}px). Минимально допустимая высота {{ min_height }}px. + + + This value should be the user's current password. + Значение должно быть текущим паролем пользователя. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Значение должно быть равно {{ limit }} символу.|Значение должно быть равно {{ limit }} символам.|Значение должно быть равно {{ limit }} символам. + + + The file was only partially uploaded. + Файл был загружен только частично. + + + No file was uploaded. + Файл не был загружен. + + + No temporary folder was configured in php.ini. + Не настроена временная директория в php.ini. + + + Cannot write temporary file to disk. + Невозможно записать временный файл на диск. + + + A PHP extension caused the upload to fail. + Расширение PHP вызвало ошибку при загрузке. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Эта коллекция должна содержать {{ limit }} элемент или больше.|Эта коллекция должна содержать {{ limit }} элемента или больше.|Эта коллекция должна содержать {{ limit }} элементов или больше. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Эта коллекция должна содержать {{ limit }} элемент или меньше.|Эта коллекция должна содержать {{ limit }} элемента или меньше.|Эта коллекция должна содержать {{ limit }} элементов или меньше. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Эта коллекция должна содержать ровно {{ limit }} элемент.|Эта коллекция должна содержать ровно {{ limit }} элемента.|Эта коллекция должна содержать ровно {{ limit }} элементов. + + + Invalid card number. + Неверный номер карты. + + + Unsupported card type or invalid card number. + Неподдерживаемый тип или неверный номер карты. + + + This is not a valid International Bank Account Number (IBAN). + Значение не является допустимым международным номером банковского счета (IBAN). + + + This value is not a valid ISBN-10. + Значение имеет неверный формат ISBN-10. + + + This value is not a valid ISBN-13. + Значение имеет неверный формат ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Значение не соответствует форматам ISBN-10 и ISBN-13. + + + This value is not a valid ISSN. + Значение не соответствует формату ISSN. + + + This value is not a valid currency. + Некорректный формат валюты. + + + This value should be equal to {{ compared_value }}. + Значение должно быть равно {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Значение должно быть больше чем {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Значение должно быть больше или равно {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Значение должно быть идентичным {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Значение должно быть меньше чем {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Значение должно быть меньше или равно {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Значение не должно быть равно {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Значение не должно быть идентичным {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Соотношение сторон изображения слишком велико ({{ ratio }}). Максимальное соотношение сторон {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Соотношение сторон изображения слишком мало ({{ ratio }}). Минимальное соотношение сторон {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Изображение квадратное ({{ width }}x{{ height }}px). Квадратные изображения не разрешены. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Изображение в альбомной ориентации ({{ width }}x{{ height }}px). Изображения в альбомной ориентации не разрешены. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Изображение в портретной ориентации ({{ width }}x{{ height }}px). Изображения в портретной ориентации не разрешены. + + + An empty file is not allowed. + Пустые файлы не разрешены. + + + This value does not match the expected {{ charset }} charset. + Значение не совпадает с ожидаемой {{ charset }} кодировкой. + + + + 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 @@ + + + + + + This value should be false. + Táto hodnota by mala byť nastavená na false. + + + This value should be true. + Táto hodnota by mala byť nastavená na true. + + + This value should be of type {{ type }}. + Táto hodnota by mala byť typu {{ type }}. + + + This value should be blank. + Táto hodnota by mala byť prázdna. + + + The value you selected is not a valid choice. + Táto hodnota by mala byť jednou z poskytnutých možností. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Mali by ste vybrať minimálne {{ limit }} možnosť.|Mali by ste vybrať minimálne {{ limit }} možnosti.|Mali by ste vybrať minimálne {{ limit }} možností. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Mali by ste vybrať najviac {{ limit }} možnosť.|Mali by ste vybrať najviac {{ limit }} možnosti.|Mali by ste vybrať najviac {{ limit }} možností. + + + One or more of the given values is invalid. + Niektoré z uvedených hodnôt sú neplatné. + + + This field was not expected. + Toto pole sa neočakáva. + + + This field is missing. + Toto pole chýba. + + + This value is not a valid date. + Tato hodnota nemá platný formát dátumu. + + + This value is not a valid datetime. + Táto hodnota nemá platný formát dátumu a času. + + + This value is not a valid email address. + Táto hodnota nie je platná emailová adresa. + + + The file could not be found. + Súbor sa nenašiel. + + + The file is not readable. + Súbor nie je čitateľný. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Súbor je príliš veľký ({{ size }} {{ suffix }}). Maximálna povolená veľkosť je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Súbor typu ({{ type }}) nie je podporovaný. Podporované typy sú {{ types }}. + + + This value should be {{ limit }} or less. + Táto hodnota by mala byť {{ limit }} alebo menej. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Táto hodnota obsahuje viac znakov ako je povolené. Mala by obsahovať najviac {{ limit }} znak.|Táto hodnota obsahuje viac znakov ako je povolené. Mala by obsahovať najviac {{ limit }} znaky.|Táto hodnota obsahuje viac znakov ako je povolené. Mala by obsahovať najviac {{ limit }} znakov. + + + This value should be {{ limit }} or more. + Táto hodnota by mala byť viac ako {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Táto hodnota je príliš krátka. Musí obsahovať minimálne {{ limit }} znak.|Táto hodnota je príliš krátka. Musí obsahovať minimálne {{ limit }} znaky.|Táto hodnota je príliš krátka. Minimálny počet znakov je {{ limit }}. + + + This value should not be blank. + Táto hodnota by mala byť vyplnená. + + + This value should not be null. + Táto hodnota by nemala byť null. + + + This value should be null. + Táto hodnota by mala byť null. + + + This value is not valid. + Táto hodnota nie je platná. + + + This value is not a valid time. + Tato hodnota nemá správny formát času. + + + This value is not a valid URL. + Táto hodnota nie je platnou URL adresou. + + + The two values should be equal. + Tieto dve hodnoty by mali byť rovnaké. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Súbor je príliš veľký. Maximálna povolená veľkosť je {{ limit }} {{ suffix }}. + + + The file is too large. + Súbor je príliš veľký. + + + The file could not be uploaded. + Súbor sa nepodarilo nahrať. + + + This value should be a valid number. + Táto hodnota by mala byť číslo. + + + This file is not a valid image. + Tento súbor nie je obrázok. + + + This is not a valid IP address. + Toto nie je platná IP adresa. + + + This value is not a valid language. + Tento jazyk neexistuje. + + + This value is not a valid locale. + Táto lokalizácia neexistuje. + + + This value is not a valid country. + Táto krajina neexistuje. + + + This value is already used. + Táto hodnota sa už používa. + + + The size of the image could not be detected. + Nepodarilo sa zistiť rozmery obrázku. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Obrázok je príliš široký ({{ width }}px). Maximálna povolená šírka obrázku je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Obrázok je príliš úzky ({{ width }}px). Minimálna šírka obrázku by mala byť {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + >Obrázok je príliš vysoký ({{ height }}px). Maximálna povolená výška obrázku je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Obrázok je príliš nízky ({{ height }}px). Minimálna výška obrázku by mala byť {{ min_height }}px. + + + This value should be the user's current password. + Táto hodnota by mala byť aktuálne heslo používateľa. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Táto hodnota by mala mať presne {{ limit }} znak.|Táto hodnota by mala mať presne {{ limit }} znaky.|Táto hodnota by mala mať presne {{ limit }} znakov. + + + The file was only partially uploaded. + Bola nahraná len časť súboru. + + + No file was uploaded. + Žiadny súbor nebol nahraný. + + + No temporary folder was configured in php.ini. + V php.ini nie je nastavená cesta k adresáru pre dočasné súbory. + + + Cannot write temporary file to disk. + Dočasný súbor sa nepodarilo zapísať na disk. + + + A PHP extension caused the upload to fail. + Rozšírenie PHP zabránilo nahraniu súboru. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Táto kolekcia by mala obsahovať aspoň {{ limit }} prvok alebo viac.|Táto kolekcia by mala obsahovať aspoň {{ limit }} prvky alebo viac.|Táto kolekcia by mala obsahovať aspoň {{ limit }} prvkov alebo viac. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Táto kolekcia by mala maximálne {{ limit }} prvok.|Táto kolekcia by mala obsahovať maximálne {{ limit }} prvky.|Táto kolekcia by mala obsahovať maximálne {{ limit }} prvkov. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Táto kolekcia by mala obsahovať presne {{ limit }} prvok.|Táto kolekcia by mala obsahovať presne {{ limit }} prvky.|Táto kolekcia by mala obsahovať presne {{ limit }} prvkov. + + + Invalid card number. + Neplatné číslo karty. + + + Unsupported card type or invalid card number. + Nepodporovaný typ karty alebo neplatné číslo karty. + + + This is not a valid International Bank Account Number (IBAN). + Toto je neplatný IBAN. + + + This value is not a valid ISBN-10. + Táto hodnota je neplatné ISBN-10. + + + This value is not a valid ISBN-13. + Táto hodnota je neplatné ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Táto hodnota nie je platné ISBN-10 ani ISBN-13. + + + This value is not a valid ISSN. + Táto hodnota nie je platné ISSN. + + + This value is not a valid currency. + Táto hodnota nie je platná mena. + + + This value should be equal to {{ compared_value }}. + Táto hodnota by mala byť rovná {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Táto hodnota by mala byť väčšia ako {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Táto hodnota by mala byť väčšia alebo rovná {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Táto hodnota by mala byť typu {{ compared_value_type }} a zároveň by mala byť rovná {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Táto hodnota by mala byť menšia ako {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Táto hodnota by mala byť menšia alebo rovná {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Táto hodnota by nemala byť rovná {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Táto hodnota by nemala byť typu {{ compared_value_type }} a zároveň by nemala byť rovná {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Pomer strán obrázku je príliš veľký ({{ ratio }}). Maximálny povolený pomer strán obrázku je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Pomer strán obrázku je príliš malý ({{ ratio }}). Minimálny povolený pomer strán obrázku je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Strany obrázku sú štvorcové ({{ width }}x{{ height }}px). Štvorcové obrázky nie sú povolené. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Obrázok je orientovaný na šírku ({{ width }}x{{ height }}px). Obrázky orientované na šírku nie sú povolené. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Obrázok je orientovaný na výšku ({{ width }}x{{ height }}px). Obrázky orientované na výšku nie sú povolené. + + + An empty file is not allowed. + Súbor nesmie byť prázdny. + + + + 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 @@ + + + + + + This value should be false. + Vrednost bi morala biti nepravilna (false). + + + This value should be true. + Vrednost bi morala biti pravilna (true). + + + This value should be of type {{ type }}. + Vrednost mora biti naslednjega tipa {{ type }}. + + + This value should be blank. + Vrednost mora biti prazna. + + + The value you selected is not a valid choice. + Vrednost, ki ste jo izbrali, ni veljavna možnost. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Izbrati morate vsaj {{ limit }} možnost.|Izbrati morate vsaj {{ limit }} možnosti.|Izbrati morate vsaj {{ limit }} možnosti.|Izbrati morate vsaj {{ limit }} možnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Izberete lahko največ {{ limit }} možnost.|Izberete lahko največ {{ limit }} možnosti.|Izberete lahko največ {{ limit }} možnosti.|Izberete lahko največ {{ limit }} možnosti. + + + One or more of the given values is invalid. + Ena ali več podanih vrednosti ni veljavnih. + + + This field was not expected. + To polje ni bilo pričakovati. + + + This field is missing. + To polje manjka. + + + This value is not a valid date. + Ta vrednost ni veljaven datum. + + + This value is not a valid datetime. + Ta vrednost ni veljaven datum in čas. + + + This value is not a valid email address. + Ta vrednost ni veljaven e-poštni naslov. + + + The file could not be found. + Datoteke ni mogoče najti. + + + The file is not readable. + Datoteke ni mogoče prebrati. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika ({{ size }} {{ suffix }}). Največja dovoljena velikost je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime tip datoteke je neveljaven ({{ type }}). Dovoljeni mime tipi so {{ types }}. + + + This value should be {{ limit }} or less. + Ta vrednost bi morala biti {{ limit }} ali manj. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ta vrednost je predolga. Morala bi imeti {{ limit }} znak ali manj.|Ta vrednost je predolga. Morala bi imeti {{ limit }} znaka ali manj.|Ta vrednost je predolga. Morala bi imeti {{ limit }} znake ali manj.|Ta vrednost je predolga. Morala bi imeti {{ limit }} znakov ali manj. + + + This value should be {{ limit }} or more. + Ta vrednost bi morala biti {{ limit }} ali več. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ta vrednost je prekratka. Morala bi imeti {{ limit }} znak ali več.|Ta vrednost je prekratka. Morala bi imeti {{ limit }} znaka ali več.|Ta vrednost je prekratka. Morala bi imeti {{ limit }} znake ali več.|Ta vrednost je prekratka. Morala bi imeti {{ limit }} znakov ali več. + + + This value should not be blank. + Ta vrednost ne bi smela biti prazna. + + + This value should not be null. + Ta vrednost ne bi smela biti nedefinirana (null). + + + This value should be null. + Ta vrednost bi morala biti nedefinirana (null). + + + This value is not valid. + Ta vrednost ni veljavna. + + + This value is not a valid time. + Ta vrednost ni veljaven čas. + + + This value is not a valid URL. + Ta vrednost ni veljaven URL. + + + The two values should be equal. + Ti dve vrednosti bi morali biti enaki. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika. Največja dovoljena velikost je {{ limit }} {{ suffix }}. + + + The file is too large. + Datoteka je prevelika. + + + The file could not be uploaded. + Datoteke ni bilo mogoče naložiti. + + + This value should be a valid number. + Ta vrednost bi morala biti veljavna številka. + + + This file is not a valid image. + Ta datoteka ni veljavna slika. + + + This is not a valid IP address. + To ni veljaven IP naslov. + + + This value is not a valid language. + Ta vrednost ni veljaven jezik. + + + This value is not a valid locale. + Ta vrednost ni veljavna lokalnost. + + + This value is not a valid country. + Ta vrednost ni veljavna država. + + + This value is already used. + Ta vrednost je že uporabljena. + + + The size of the image could not be detected. + Velikosti slike ni bilo mogoče zaznati. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je preširoka ({{ width }}px). Največja dovoljena širina je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premajhna ({{ width }}px). Najmanjša predvidena širina je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Višina slike je prevelika ({{ height }}px). Največja dovoljena višina je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Višina slike je premajhna ({{ height }}px). Najmanjša predvidena višina je {{ min_height }}px. + + + This value should be the user's current password. + Ta vrednost bi morala biti trenutno uporabnikovo geslo. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ta vrednost bi morala imeti točno {{ limit }} znak.|Ta vrednost bi morala imeti točno {{ limit }} znaka.|Ta vrednost bi morala imeti točno {{ limit }} znake.|Ta vrednost bi morala imeti točno {{ limit }} znakov. + + + The file was only partially uploaded. + Datoteka je bila le delno naložena. + + + No file was uploaded. + Nobena datoteka ni bila naložena. + + + No temporary folder was configured in php.ini. + Začasna mapa ni nastavljena v php.ini. + + + Cannot write temporary file to disk. + Začasne datoteke ni bilo mogoče zapisati na disk. + + + A PHP extension caused the upload to fail. + PHP razširitev je vzrok, da nalaganje ni uspelo. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ta zbirka bi morala vsebovati {{ limit }} element ali več.|Ta zbirka bi morala vsebovati {{ limit }} elementa ali več.|Ta zbirka bi morala vsebovati {{ limit }} elemente ali več.|Ta zbirka bi morala vsebovati {{ limit }} elementov ali več. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ta zbirka bi morala vsebovati {{ limit }} element ali manj.|Ta zbirka bi morala vsebovati {{ limit }} elementa ali manj.|Ta zbirka bi morala vsebovati {{ limit }} elemente ali manj.|Ta zbirka bi morala vsebovati {{ limit }} elementov ali manj. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ta zbirka bi morala vsebovati točno {{ limit }} element.|Ta zbirka bi morala vsebovati točno {{ limit }} elementa.|Ta zbirka bi morala vsebovati točno {{ limit }} elemente.|Ta zbirka bi morala vsebovati točno {{ limit }} elementov. + + + Invalid card number. + Neveljavna številka kartice. + + + Unsupported card type or invalid card number. + Nepodprti tip kartice ali neveljavna številka kartice. + + + This is not a valid International Bank Account Number (IBAN). + To ni veljavna mednarodna številka bančnega računa (IBAN). + + + This value is not a valid ISBN-10. + Neveljavna vrednost po ISBN-10. + + + This value is not a valid ISBN-13. + Neveljavna vrednost po ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Neveljavna vrednost po ISBN-10 ali po ISBN-13. + + + This value is not a valid ISSN. + Neveljavna vrednost ISSN. + + + This value is not a valid currency. + Ta vrednost ni veljavna valuta. + + + This value should be equal to {{ compared_value }}. + Ta vrednost bi morala biti enaka {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ta vrednost bi morala biti večja od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ta vrednost bi morala biti večja ali enaka {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ta vrednost bi morala biti identična {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ta vrednost bi morala biti manjša od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ta vrednost bi morala biti manjša ali enaka {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ta vrednost ne bi smela biti enaka {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ta vrednost ne bi smela biti identična {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Razmerje slike je preveliko ({{ ratio }}). Največje dovoljeno razmerje je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Razmerje slike je premajhno ({{ ratio }}). Najmanjše pričakovano razmerje je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Slika je kvadrat ({{ width }}x{{ height }}px). Kvadratne slike niso dovoljene. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Slika je ležeče usmerjena ({{ width }}x{{ height }}px). Ležeče usmerjene slike niso dovoljene. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Slika je pokončno usmerjena ({{ width }}x{{ height }}px). Pokončno usmerjene slike niso dovoljene. + + + An empty file is not allowed. + Prazna datoteka ni dovoljena. + + + This value does not match the expected {{ charset }} charset. + Ta vrednost se ne ujema s pričakovanim naborom znakov {{ charset }}. + + + + 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 @@ + + + + + + This value should be false. + Kjo vlerë duhet të jetë e pavërtetë (false). + + + This value should be true. + Kjo vlerë duhet të jetë e vërtetë (true). + + + This value should be of type {{ type }}. + Kjo vlerë duhet të jetë e llojit {{ type }}. + + + This value should be blank. + Kjo vlerë duhet të jetë e zbrazët. + + + The value you selected is not a valid choice. + Vlera që keni zgjedhur nuk është alternativë e vlefshme. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Duhet të zgjedhni së paku {{ limit }} alternativa.|Duhet të zgjedhni së paku {{ limit }} alternativa. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Duhet të zgjedhni më së shumti {{ limit }} alternativa.|Duhet të zgjedhni më së shumti {{ limit }} alternativa. + + + One or more of the given values is invalid. + Një apo më shumë nga vlerat e dhëna nuk janë të sakta. + + + This field was not expected. + Kjo fushë nuk pritej. + + + This field is missing. + Kjo fushë është zhdukur. + + + This value is not a valid date. + Kjo vlerë nuk është datë e vlefshme. + + + This value is not a valid datetime. + Kjo vlerë nuk është datë-kohë e vlefshme. + + + This value is not a valid email address. + Kjo vlerë nuk është e-mail adresë e vlefshme. + + + The file could not be found. + File nuk mund të gjindej. + + + The file is not readable. + File nuk është i lexueshëm. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + File është shumë i madh ({{ size }} {{ suffix }}). Madhësia më e madhe e lejuar është {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Lloji mime i files nuk është i vlefshëm ({{ type }}). Llojet mime të lejuara janë {{ types }}. + + + This value should be {{ limit }} or less. + Kjo vlerë duhet të jetë {{ limit }} ose më pak. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Kjo vlerë është shumë e gjatë. Duhet t'i ketë {{ limit }} ose më pak karaktere.|Kjo vlerë është shumë e gjatë. Duhet t'i ketë {{ limit }} ose më pak karaktere. + + + This value should be {{ limit }} or more. + Kjo vlerë duhet të jetë {{ limit }} ose më shumë. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Kjo vlerë është shumë e shkurtër. Duhet t'i ketë {{ limit }} ose më shumë karaktere.|Kjo vlerë është shumë e shkurtër. Duhet t'i ketë {{ limit }} ose më shumë karaktere. + + + This value should not be blank. + Kjo vlerë nuk duhet të jetë e zbrazët. + + + This value should not be null. + Kjo vlerë nuk duhet të jetë null. + + + This value should be null. + Kjo vlerë duhet të jetë null. + + + This value is not valid. + Kjo vlerë nuk është e vlefshme. + + + This value is not a valid time. + Kjo vlerë nuk është kohë e vlefshme. + + + This value is not a valid URL. + Kjo vlerë nuk është URL e vlefshme. + + + The two values should be equal. + Këto dy vlera duhet të jenë të barabarta. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ky file është shumë i madh. Madhësia maksimale e lejuar është {{ limit }} {{ suffix }}. + + + The file is too large. + Ky file është shumë i madh. + + + The file could not be uploaded. + Ky file nuk mund të ngarkohet. + + + This value should be a valid number. + Kjo vlerë duhet të jetë numër i vlefshëm. + + + This file is not a valid image. + Ky file nuk është imazh i vlefshëm. + + + This is not a valid IP address. + Kjo vlerë nuk është IP adresë e vlefshme. + + + This value is not a valid language. + Kjo vlerë nuk është gjuhë e vlefshme. + + + This value is not a valid locale. + Kjo vlerë nuk është përcaktim rajonal i vlefshëm. + + + This value is not a valid country. + Kjo vlerë nuk është shtet i vlefshëm. + + + This value is already used. + Kjo vlerë është tashmë në përdorim. + + + The size of the image could not be detected. + Madhësia e këtij imazhi nuk mund të zbulohet. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Gjerësia e imazhit është shumë e madhe ({{ width }}px). Gjerësia maksimale e lejuar është {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Gjerësia e imazhit është shumë e vogël ({{ width }}px). Gjerësia minimale e pritur është {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Gjatësia e imazhit është shumë e madhe ({{ height }}px). Gjatësia maksimale e lejuar është {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Gjatësia e imazhit është shumë e vogël ({{ height }}px). Gjatësia minimale e pritur është {{ min_height }}px. + + + This value should be the user's current password. + Kjo vlerë duhet të jetë fjalëkalimi aktual i përdoruesit. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere.|Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere. + + + The file was only partially uploaded. + Ky file është ngarkuar pjesërisht. + + + No file was uploaded. + Nuk është ngarkuar ndonjë file. + + + No temporary folder was configured in php.ini. + Asnjë folder i përkohshëm nuk është konfiguruar në php.ini. + + + Cannot write temporary file to disk. + Nuk mund të shkruhet file i përkohshëm në disk. + + + A PHP extension caused the upload to fail. + Një ekstenzion i PHP-së bëri të dështojë ngarkimi i files. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.|Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.|Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ky kolekcion duhet të përmbajë saktësisht {{ limit }} elemente.|Ky kolekcion duhet të përmbajë saktësisht {{ limit }} elemente. + + + Invalid card number. + Numër kartele i pavlefshëm. + + + Unsupported card type or invalid card number. + Lloj kartele i pambështetur ose numër kartele i pavlefshëm. + + + + 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 @@ + + + + + + This value should be false. + Вредност треба да буде нетачна. + + + This value should be true. + Вредност треба да буде тачна. + + + This value should be of type {{ type }}. + Вредност треба да буде типа {{ type }}. + + + This value should be blank. + Вредност треба да буде празна. + + + The value you selected is not a valid choice. + Вредност треба да буде једна од понуђених. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Изаберите бар {{ limit }} могућност.|Изаберите бар {{ limit }} могућности.|Изаберите бар {{ limit }} могућности. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Изаберите највише {{ limit }} могућност.|Изаберите највише {{ limit }} могућности.|Изаберите највише {{ limit }} могућности. + + + One or more of the given values is invalid. + Једна или више вредности је невалидна. + + + This field was not expected. + Ово поље не очекује. + + + This field is missing. + Ово поље недостаје. + + + This value is not a valid date. + Вредност није валидан датум. + + + This value is not a valid datetime. + Вредност није валидан датум-време. + + + This value is not a valid email address. + Вредност није валидна адреса електронске поште. + + + The file could not be found. + Датотека не може бити пронађена. + + + The file is not readable. + Датотека није читљива. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Датотека је превелика ({{ size }} {{ suffix }}). Највећа дозвољена величина је {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Миме тип датотеке није валидан ({{ type }}). Дозвољени миме типови су {{ types }}. + + + This value should be {{ limit }} or less. + Вредност треба да буде {{ limit }} или мање. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Вредност је предугачка. Треба да има {{ limit }} карактер или мање.|Вредност је предугачка. Треба да има {{ limit }} карактера или мање.|Вредност је предугачка. Треба да има {{ limit }} карактера или мање. + + + This value should be {{ limit }} or more. + Вредност треба да буде {{ limit }} или више. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Вредност је прекратка. Треба да има {{ limit }} карактер или више.|Вредност је прекратка. Треба да има {{ limit }} карактера или више.|Вредност је прекратка. Треба да има {{ limit }} карактера или више. + + + This value should not be blank. + Вредност не треба да буде празна. + + + This value should not be null. + Вредност не треба да буде null. + + + This value should be null. + Вредност треба да буде null. + + + This value is not valid. + Вредност је невалидна. + + + This value is not a valid time. + Вредност није валидно време. + + + This value is not a valid URL. + Вредност није валидан URL. + + + The two values should be equal. + Обе вредности треба да буду једнаке. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Датотека је превелика. Највећа дозвољена величина је {{ limit }} {{ suffix }}. + + + The file is too large. + Датотека је превелика. + + + The file could not be uploaded. + Датотека не може бити отпремљена. + + + This value should be a valid number. + Вредност треба да буде валидан број. + + + This file is not a valid image. + Ова датотека није валидна слика. + + + This is not a valid IP address. + Ово није валидна ИП адреса. + + + This value is not a valid language. + Вредност није валидан језик. + + + This value is not a valid locale. + Вредност није валидан локал. + + + This value is not a valid country. + Вредност није валидна земља. + + + This value is already used. + Вредност је већ искоришћена. + + + The size of the image could not be detected. + Величина слике не може бити одређена. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина слике је превелика ({{ width }}px). Најећа дозвољена ширина је {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина слике је премала ({{ width }}px). Најмања дозвољена ширина је {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висина слике је превелика ({{ height }}px). Најећа дозвољена висина је {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висина слике је премала ({{ height }}px). Најмања дозвољена висина је {{ min_height }}px. + + + This value should be the user's current password. + Вредност треба да буде тренутна корисничка лозинка. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Вредност треба да има тачно {{ limit }} карактер.|Вредност треба да има тачно {{ limit }} карактера.|Вредност треба да има тачно {{ limit }} карактера. + + + The file was only partially uploaded. + Датотека је само парцијално отпремљена. + + + No file was uploaded. + Датотека није отпремљена. + + + No temporary folder was configured in php.ini. + Привремени директоријум није конфигурисан у php.ini. + + + Cannot write temporary file to disk. + Немогуће писање привремене датотеке на диск. + + + A PHP extension caused the upload to fail. + PHP екстензија је проузроковала неуспех отпремања датотеке. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ова колекција треба да садржи {{ limit }} или више елемената.|Ова колекција треба да садржи {{ limit }} или више елемената.|Ова колекција треба да садржи {{ limit }} или више елемената. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ова колекција треба да садржи {{ limit }} или мање елемената.|Ова колекција треба да садржи {{ limit }} или мање елемената.|Ова колекција треба да садржи {{ limit }} или мање елемената. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ова колекција треба да садржи тачно {{ limit }} елемент.|Ова колекција треба да садржи тачно {{ limit }} елемента.|Ова колекција треба да садржи тачно {{ limit }} елемената. + + + Invalid card number. + Невалидан број картице. + + + Unsupported card type or invalid card number. + Невалидан број картице или тип картице није подржан. + + + This is not a valid International Bank Account Number (IBAN). + Ово није валидан међународни број банковног рачуна (IBAN). + + + This value is not a valid ISBN-10. + Ово није валидан ISBN-10. + + + This value is not a valid ISBN-13. + Ово није валидан ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ово није валидан ISBN-10 или ISBN-13. + + + This value is not a valid ISSN. + Ово није валидан ISSN. + + + This value is not a valid currency. + Ово није валидна валута. + + + This value should be equal to {{ compared_value }}. + Ова вредност треба да буде {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ова вредност треба да буде већа од {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ова вредност треба да буде већа или једнака {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ова вредност треба да буде идентична са {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ова вредност треба да буде мања од {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ова вредност треба да буде мања или једнака {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ова вредност не треба да буде једнака {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ова вредност не треба да буде идентична са {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Размера ове слике је превелика ({{ ratio }}). Максимална дозвољена размера је {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Размера ове слике је премала ({{ ratio }}). Минимална очекивана размера је {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Слика је квадратна ({{ width }}x{{ height }}px). Квадратне слике нису дозвољене. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Слика је оријентације пејзажа ({{ width }}x{{ height }}px). Пејзажна оријентација слика није дозвољена. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Слика је оријантације портрета ({{ width }}x{{ height }}px). Портретна оријентација слика није дозвољена. + + + + 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 @@ + + + + + + This value should be false. + Vrednost treba da bude netačna. + + + This value should be true. + Vrednost treba da bude tačna. + + + This value should be of type {{ type }}. + Vrednost treba da bude tipa {{ type }}. + + + This value should be blank. + Vrednost treba da bude prazna. + + + The value you selected is not a valid choice. + Vrednost treba da bude jedna od ponuđenih. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Izaberite bar {{ limit }} mogućnost.|Izaberite bar {{ limit }} mogućnosti.|Izaberite bar {{ limit }} mogućnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Izaberite najviše {{ limit }} mogućnost.|Izaberite najviše {{ limit }} mogućnosti.|Izaberite najviše {{ limit }} mogućnosti. + + + One or more of the given values is invalid. + Jedna ili više vrednosti je nevalidna. + + + This field was not expected. + Ovo polje ne očekuje. + + + This field is missing. + Ovo polje nedostaje. + + + This value is not a valid date. + Vrednost nije validan datum. + + + This value is not a valid datetime. + Vrednost nije validan datum-vreme. + + + This value is not a valid email address. + Vrednost nije validna adresa elektronske pošte. + + + The file could not be found. + Datoteka ne može biti pronađena. + + + The file is not readable. + Datoteka nije čitljiva. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime tip datoteke nije validan ({{ type }}). Dozvoljeni mime tipovi su {{ types }}. + + + This value should be {{ limit }} or less. + Vrednost treba da bude {{ limit }} ili manje. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Vrednost je predugačka. Treba da ima {{ limit }} karakter ili manje.|Vrednost je predugačka. Treba da ima {{ limit }} karaktera ili manje.|Vrednost je predugačka. Treba da ima {{ limit }} karaktera ili manje. + + + This value should be {{ limit }} or more. + Vrednost treba da bude {{ limit }} ili više. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Vrednost je prekratka. Treba da ima {{ limit }} karakter ili više.|Vrednost je prekratka. Treba da ima {{ limit }} karaktera ili više.|Vrednost je prekratka. Treba da ima {{ limit }} karaktera ili više. + + + This value should not be blank. + Vrednost ne treba da bude prazna. + + + This value should not be null. + Vrednost ne treba da bude null. + + + This value should be null. + Vrednost treba da bude null. + + + This value is not valid. + Vrednost je nevalidna. + + + This value is not a valid time. + Vrednost nije validno vreme. + + + This value is not a valid URL. + Vrednost nije validan URL. + + + The two values should be equal. + Obe vrednosti treba da budu jednake. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The file is too large. + Datoteka je prevelika. + + + The file could not be uploaded. + Datoteka ne može biti otpremljena. + + + This value should be a valid number. + Vrednost treba da bude validan broj. + + + This file is not a valid image. + Ova datoteka nije validna slika. + + + This is not a valid IP address. + Ovo nije validna IP adresa. + + + This value is not a valid language. + Vrednost nije validan jezik. + + + This value is not a valid locale. + Vrednost nije validan lokal. + + + This value is not a valid country. + Vrednost nije validna zemlja. + + + This value is already used. + Vrednost je već iskorišćena. + + + The size of the image could not be detected. + Veličina slike ne može biti određena. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je prevelika ({{ width }}px). Najeća dozvoljena širina je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premala ({{ width }}px). Najmanja dozvoljena širina je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Visina slike je prevelika ({{ height }}px). Najeća dozvoljena visina je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Visina slike je premala ({{ height }}px). Najmanja dozvoljena visina je {{ min_height }}px. + + + This value should be the user's current password. + Vrednost treba da bude trenutna korisnička lozinka. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Vrednost treba da ima tačno {{ limit }} karakter.|Vrednost treba da ima tačno {{ limit }} karaktera.|Vrednost treba da ima tačno {{ limit }} karaktera. + + + The file was only partially uploaded. + Datoteka je samo parcijalno otpremljena. + + + No file was uploaded. + Datoteka nije otpremljena. + + + No temporary folder was configured in php.ini. + Privremeni direktorijum nije konfigurisan u php.ini. + + + Cannot write temporary file to disk. + Nemoguće pisanje privremene datoteke na disk. + + + A PHP extension caused the upload to fail. + PHP ekstenzija je prouzrokovala neuspeh otpremanja datoteke. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ova kolekcija treba da sadrži {{ limit }} ili više elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili više elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili više elemenata. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ova kolekcija treba da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili manje elemenata. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ova kolekcija treba da sadrži tačno {{ limit }} element.|Ova kolekcija treba da sadrži tačno {{ limit }} elementa.|Ova kolekcija treba da sadrži tačno {{ limit }} elemenata. + + + Invalid card number. + Nevalidan broj kartice. + + + Unsupported card type or invalid card number. + Nevalidan broj kartice ili tip kartice nije podržan. + + + This is not a valid International Bank Account Number (IBAN). + Ovo nije validan međunarodni broj bankovnog računa (IBAN). + + + This value is not a valid ISBN-10. + Ovo nije validan ISBN-10. + + + This value is not a valid ISBN-13. + Ovo nije validan ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ovo nije validan ISBN-10 ili ISBN-13. + + + This value is not a valid ISSN. + Ovo nije validan ISSN. + + + This value is not a valid currency. + Ovo nije validna valuta. + + + This value should be equal to {{ compared_value }}. + Ova vrednost treba da bude {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ova vrednost treba da bude veća od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ova vrednost treba da bude veća ili jednaka {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrednost treba da bude identična sa {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ova vrednost treba da bude manja od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ova vrednost treba da bude manja ili jednaka {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ova vrednost ne treba da bude jednaka {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrednost ne treba da bude identična sa {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Razmera ove slike je prevelika ({{ ratio }}). Maksimalna dozvoljena razmera je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Razmera ove slike je premala ({{ ratio }}). Minimalna očekivana razmera je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Slika je kvadratna ({{ width }}x{{ height }}px). Kvadratne slike nisu dozvoljene. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Slika je orijentacije pejzaža ({{ width }}x{{ height }}px). Pejzažna orijentacija slika nije dozvoljena. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Slika je orijantacije portreta ({{ width }}x{{ height }}px). Portretna orijentacija slika nije dozvoljena. + + + + 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 @@ + + + + + + This value should be false. + Värdet ska vara falskt. + + + This value should be true. + Värdet ska vara sant. + + + This value should be of type {{ type }}. + Värdet ska vara av typen {{ type }}. + + + This value should be blank. + Värdet ska vara tomt. + + + The value you selected is not a valid choice. + Värdet ska vara ett av de givna valen. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du måste välja minst {{ limit }} val.|Du måste välja minst {{ limit }} val. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan som mest välja {{ limit }} val.|Du kan som mest välja {{ limit }} val. + + + One or more of the given values is invalid. + Ett eller fler av de angivna värdena är ogiltigt. + + + This field was not expected. + Det här fältet förväntades inte. + + + This field is missing. + Det här fältet saknas. + + + This value is not a valid date. + Värdet är inte ett giltigt datum. + + + This value is not a valid datetime. + Värdet är inte ett giltigt datum med tid. + + + This value is not a valid email address. + Värdet är inte en giltig epost-adress. + + + The file could not be found. + Filen kunde inte hittas. + + + The file is not readable. + Filen är inte läsbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Filen är för stor ({{ size }} {{ suffix }}). Största tillåtna storlek är {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Filens MIME-typ ({{ type }}) är ogiltig. De tillåtna typerna är {{ types }}. + + + This value should be {{ limit }} or less. + Värdet ska vara {{ limit }} eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Värdet är för långt. Det ska ha {{ limit }} tecken eller färre.|Värdet är för långt. Det ska ha {{ limit }} tecken eller färre. + + + This value should be {{ limit }} or more. + Värdet ska vara {{ limit }} eller mer. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Värdet är för kort. Det ska ha {{ limit }} tecken eller mer.|Värdet är för kort. Det ska ha {{ limit }} tecken eller mer. + + + This value should not be blank. + Värdet kan inte vara tomt. + + + This value should not be null. + Värdet kan inte vara null. + + + This value should be null. + Värdet ska vara null. + + + This value is not valid. + Värdet är inte giltigt. + + + This value is not a valid time. + Värdet är inte en giltig tid. + + + This value is not a valid URL. + Värdet är inte en giltig URL. + + + The two values should be equal. + De två värdena måste vara lika. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Filen är för stor. Tillåten maximal storlek är {{ limit }} {{ suffix }}. + + + The file is too large. + Filen är för stor. + + + The file could not be uploaded. + Filen kunde inte laddas upp. + + + This value should be a valid number. + Värdet ska vara ett giltigt nummer. + + + This file is not a valid image. + Filen är ingen giltig bild. + + + This is not a valid IP address. + Det här är inte en giltig IP-adress. + + + This value is not a valid language. + Värdet är inte ett giltigt språk. + + + This value is not a valid locale. + Värdet är inte en giltig plats. + + + This value is not a valid country. + Värdet är inte ett giltigt land. + + + This value is already used. + Värdet används redan. + + + The size of the image could not be detected. + Det gick inte att fastställa storleken på bilden. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Bildens bredd är för stor ({{ width }}px). Tillåten maximal bredd är {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Bildens bredd är för liten ({{ width }}px). Minsta förväntade bredd är {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Bildens höjd är för stor ({{ height }}px). Tillåten maximal bredd är {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Bildens höjd är för liten ({{ height }}px). Minsta förväntade höjd är {{ min_height }}px. + + + This value should be the user's current password. + Värdet ska vara användarens nuvarande lösenord. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Värdet ska ha exakt {{ limit }} tecken.|Värdet ska ha exakt {{ limit }} tecken. + + + The file was only partially uploaded. + Filen laddades bara upp delvis. + + + No file was uploaded. + Ingen fil laddades upp. + + + No temporary folder was configured in php.ini. + Det finns ingen temporär mapp konfigurerad i php.ini. + + + Cannot write temporary file to disk. + Kan inte skriva temporär fil till disken. + + + A PHP extension caused the upload to fail. + En PHP extension gjorde att uppladdningen misslyckades. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Den här samlingen ska innehålla {{ limit }} element eller mer.|Den här samlingen ska innehålla {{ limit }} element eller mer. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Den här samlingen ska innehålla {{ limit }} element eller mindre.|Den här samlingen ska innehålla {{ limit }} element eller mindre. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Den här samlingen ska innehålla exakt {{ limit }} element.|Den här samlingen ska innehålla exakt {{ limit }} element. + + + Invalid card number. + Ogiltigt kortnummer. + + + Unsupported card type or invalid card number. + Okänd korttyp eller ogiltigt kortnummer. + + + This is not a valid International Bank Account Number (IBAN). + Det här är inte en giltig International Bank Account Number (IBANK). + + + This value is not a valid ISBN-10. + Värdet är inte en giltig ISBN-10. + + + This value is not a valid ISBN-13. + Värdet är inte en giltig ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Värdet är varken en giltig ISBN-10 eller en giltig ISBN-13. + + + This value is not a valid ISSN. + Värdet är inte en giltig ISSN. + + + This value is not a valid currency. + Värdet är inte en giltig valuta. + + + This value should be equal to {{ compared_value }}. + Värdet ska vara detsamma som {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Värdet ska vara större än {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Värdet ska bara större än eller detsamma som {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Värdet ska vara identiskt till {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Värdet ska vara mindre än {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Värdet ska vara mindre än eller detsamma som {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Värdet ska inte vara detsamma som {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Värdet ska inte vara identiskt med {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Förhållandet mellan bildens bredd och höjd är för stort ({{ ratio }}). Högsta tillåtna förhållande är {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Förhållandet mellan bildens bredd och höjd är för litet ({{ ratio }}). Minsta tillåtna förhållande är {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Bilden är kvadratisk ({{ width }}x{{ height }}px). Kvadratiska bilder tillåts inte. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Bilden är landskapsorienterad ({{ width }}x{{ height }}px). Landskapsorienterade bilder tillåts inte. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Bilden är porträttsorienterad ({{ width }}x{{ height }}px). Porträttsorienterade bilder tillåts inte. + + + An empty file is not allowed. + En tom fil är inte tillåten. + + + + 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 @@ + + + + + + This value should be false. + ค่านี้ควรจะเป็น false + + + This value should be true. + ค่านี้ควรจะเป็น true + + + This value should be of type {{ type }}. + ค่านี้ควรจะเป็นชนิด {{ type }} + + + This value should be blank. + ควรจะเป็นค่าว่าง + + + The value you selected is not a valid choice. + คุณเลือกค่าที่ไม่ตรงกับตัวเลือก + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + คุณต้องเลือกอย่างน้อย {{ limit }} ตัวเลือก + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + คุณเลือกได้มากที่สุด {{ limit }} ตัวเลือก + + + One or more of the given values is invalid. + มีบางค่าที่ส่งมาไม่ถูกต้อง + + + This field was not expected. + ฟิลด์นี้ที่ไม่ได้คาดหวัง + + + This field is missing. + ฟิลด์นี้จะหายไป + + + This value is not a valid date. + ค่าของวันที่ไม่ถูกต้อง + + + This value is not a valid datetime. + ค่าของวันที่และเวลาไม่ถูกต้อง + + + This value is not a valid email address. + ค่าของอีเมล์ไม่ถูกต้อง + + + The file could not be found. + ไม่พบไฟล์ + + + The file is not readable. + ไฟล์ไม่อยู่ในสถานะที่สามารถอ่านได้ + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + ไฟล์ใหญ่เกิน ({{ size }} {{ suffix }}) อนุญาตให้ใหญ่ที่สุดได้ไม่เกิน {{ limit }} {{ suffix }} + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime type ของไฟล์ไม่ถูกต้อง ({{ type }}) Mime types ที่อนุญาตคือ {{ types }} + + + This value should be {{ limit }} or less. + ค่านี้ควรจะเป็น {{ limit }} หรือน้อยกว่านั้น + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + ค่านี้ยาวเกินไป ควรจะมีแค่ {{ limit }} ตัวอักษรหรือน้อยกว่านั้น + + + This value should be {{ limit }} or more. + ค่านี้ควรจะมี {{ limit }} หรือมากกว่านั้น + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + ค่านี้สั้นเกินไป ควรจะมี {{ limit }} ตัวอักษรหรือมากกว่านั้น + + + This value should not be blank. + ค่านี้ไม่ควรเป็นค่าว่าง + + + This value should not be null. + ค่านี้ไม่ควรเป็นค่า null + + + This value should be null. + ค่านี้ควรเป็นค่า null + + + This value is not valid. + ค่านี้ไม่ถูกต้อง + + + This value is not a valid time. + ค่าของเวลาไม่ถูกต้อง + + + This value is not a valid URL. + ค่าของ URL ไม่ถูกต้อง + + + The two values should be equal. + ค่าทั้งสองค่าควรจะเหมือนกัน + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + ขนาดไฟล์ใหญ่เกินไป อนุญาตให้ไฟล์ขนาดใหญ่ได้ไม่เกิน {{ limit }} {{ suffix }} + + + The file is too large. + ขนาดไฟล์ใหญ่เกินไป + + + The file could not be uploaded. + ไม่สามารถอัปโหลดไฟล์ได้ + + + This value should be a valid number. + ค่าของตัวเลขไม่ถูกต้อง + + + This file is not a valid image. + ไฟล์นี้ไม่ใช่ไฟล์รูปภาพ + + + This is not a valid IP address. + ค่าของ IP ไม่ถูกต้อง + + + This value is not a valid language. + ค่าของภาษาไม่ถูกต้อง + + + This value is not a valid locale. + ค่าของภูมิภาค (Locale) ไม่ถูกต้อง + + + This value is not a valid country. + ค่าของประเทศไม่ถูกต้อง + + + This value is already used. + Tค่านี้ถูกใช้งานไปแล้ว + + + The size of the image could not be detected. + ไม่สามารถตรวจสอบขนาดไฟล์ของภาพได้ + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + ความกว้างของภาพเกินขนาด ({{ width }}px) อนุญาตให้กว้างได้มากที่สุด {{ max_width }}px + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + ความกว้างของภาพไม่ได้ขนาด ({{ width }}px) อนุญาตให้สั้นที่สุด {{ min_width }}px + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ความสูงของภาพเกินขนาด ({{ height }}px) อนุญาตให้สูงได้มากที่สุด {{ max_height }}px + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ความสูงของภาพไม่ได้ขนาด ({{ height }}px) อนุญาตให้สูงอย่างน้อยที่สุด {{ min_height }}px + + + This value should be the user current password. + ค่านี้ควรจะเป็นรหัสผ่านปัจจุบันของผู้ใช้ + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + ค่านี้ควรจะมีความยาว {{ limit }} ตัวอักษร + + + The file was only partially uploaded. + อัปโหลดไฟล์ได้เพียงบางส่วนเท่านั้น + + + No file was uploaded. + ไม่มีไฟล์ใดถูกอัปโหลด + + + No temporary folder was configured in php.ini. + ไม่พบไฟล์ temp ควรจะกำหนดใน php.ini + + + Cannot write temporary file to disk. + ไม่สามารถเขียน temp ไฟล์ลงดิสก์ได้ + + + A PHP extension caused the upload to fail. + PHP extension เกี่ยวกับการอัปโหลดมีปัญหา + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + คอเล็กชั่นนี้ควรจะประกอบไปด้วยอ่างน้อย {{ limit }} สมาชิก + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + คอเล็กชั่นนี้ไม่ควรมีสมาชิกเกิน {{ limit }} + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + คอเล็กชั่นนี้ควรจะมีสมาชิก {{ limit }} เท่านั้น + + + Invalid card number. + หมายเลขบัตรไม่ถูกต้อง + + + Unsupported card type or invalid card number. + ไม่รู้จักประเภทของบัตร หรือหมายเลขบัตรไม่ถูกต้อง + + + This is not a valid International Bank Account Number (IBAN). + นี่ไม่ถูกต้องตาม International Bank Account Number (IBAN) + + + This value is not a valid ISBN-10. + ค่านี้ไม่ถูกต้องตาม ISBN-10 + + + This value is not a valid ISBN-13. + ค่านี้ไม่ถูกต้องตาม ISBN-13 + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + ค่านี้ไม่ถูกต้องตามทั้ง ISBN-10 และ ISBN-13 + + + This value is not a valid ISSN. + ค่านี้ไม่ถุกต้องตาม ISSN + + + This value is not a valid currency. + ค่านี้ไม่ถูกต้องตามสกุลเงิน + + + This value should be equal to {{ compared_value }}. + ค่านี้ไม่ตรงกับ {{ compared_value }} + + + This value should be greater than {{ compared_value }}. + ค่านี้ควรจะมากกว่า {{ compared_value }} + + + This value should be greater than or equal to {{ compared_value }}. + ค่านี้ควรจะมากกว่าหรือตรงกับ {{ compared_value }} + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + ค่านี้ควรจะเหมือนกันกับ {{ compared_value_type }} {{ compared_value }} + + + This value should be less than {{ compared_value }}. + ค่านี้ควรจะน้อยกว่า {{ compared_value }} + + + This value should be less than or equal to {{ compared_value }}. + ค่านี้ควรจะน้อยกว่าหรือเท่ากับ {{ compared_value }} + + + This value should not be equal to {{ compared_value }}. + ค่านี้ไม่ควรเท่ากันกับ {{ compared_value }} + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + ค่านี้ไม่ควรเหมือนกันกับ {{ compared_value_type }} {{ compared_value }} + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + สัดส่วนของภาพใหญ่เกิน ({{ ratio }}) สามารถมีขนาดใหญ่ที่สุดได้ {{ max_ratio }} + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + สัดส่วนของภาพเล็กเกิน ({{ ratio }}) สามารถมีขนาดเล็กที่สุดได้ {{ min_ratio }} + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + รูปภาพเป็นจุตรัส ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นสี่เหลี่ยมจตุรัส + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + ภาพนี้เป็นแนวนอน ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นแนวนอน + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + ภาพนี้เป็นแนวตั้ง ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นแนวตั้ง + + + + 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 @@ + + + + + + This value should be false. + Bu değer olumsuz olmalıdır. + + + This value should be true. + Bu değer olumlu olmalıdır. + + + This value should be of type {{ type }}. + Bu değerin tipi {{ type }} olmalıdır. + + + This value should be blank. + Bu değer boş olmalıdır. + + + The value you selected is not a valid choice. + Seçtiğiniz değer geçerli bir seçenek değil. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + En az {{ limit }} seçenek belirtmelisiniz. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + En çok {{ limit }} seçenek belirtmelisiniz. + + + One or more of the given values is invalid. + Verilen değerlerden bir veya daha fazlası geçersiz. + + + This field was not expected. + Bu alan beklenen olmadı. + + + This field is missing. + Bu alan, eksik + + + This value is not a valid date. + Bu değer doğru bir tarih biçimi değildir. + + + This value is not a valid datetime. + Bu değer doğru bir tarihsaat biçimi değildir. + + + This value is not a valid email address. + Bu değer doğru bir e-mail adresi değildir. + + + The file could not be found. + Dosya bulunamadı. + + + The file is not readable. + Dosya okunabilir değil. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Dosya çok büyük ({{ size }} {{ suffix }}). İzin verilen en büyük dosya boyutu {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Dosyanın mime tipi geçersiz ({{ type }}). İzin verilen mime tipleri {{ types }}. + + + This value should be {{ limit }} or less. + Bu değer {{ limit }} ve altında olmalıdır. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Bu değer çok uzun. {{ limit }} karakter veya daha az olmalıdır. + + + This value should be {{ limit }} or more. + Bu değer {{ limit }} veya daha fazla olmalıdır. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Bu değer çok kısa. {{ limit }} karakter veya daha fazla olmaldır. + + + This value should not be blank. + Bu değer boş bırakılmamalıdır. + + + This value should not be null. + Bu değer boş bırakılmamalıdır. + + + This value should be null. + Bu değer boş bırakılmalıdır. + + + This value is not valid. + Bu değer geçerli değil. + + + This value is not a valid time. + Bu değer doğru bir saat değil. + + + This value is not a valid URL. + Bu değer doğru bir URL değil. + + + The two values should be equal. + İki değer eşit olmalıdır. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Dosya çok büyük. İzin verilen en büyük dosya boyutu {{ limit }} {{ suffix }}. + + + The file is too large. + Dosya çok büyük. + + + The file could not be uploaded. + Dosya yüklenemiyor. + + + This value should be a valid number. + Bu değer geçerli bir rakam olmalıdır. + + + This file is not a valid image. + Bu dosya geçerli bir resim değildir. + + + This is not a valid IP address. + Bu geçerli bir IP adresi değildir. + + + This value is not a valid language. + Bu değer geçerli bir lisan değil. + + + This value is not a valid locale. + Bu değer geçerli bir yer değildir. + + + This value is not a valid country. + Bu değer geçerli bir ülke değildir. + + + This value is already used. + Bu değer şu anda kullanımda. + + + The size of the image could not be detected. + Resmin boyutu saptanamıyor. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Resmin genişliği çok büyük ({{ width }}px). İzin verilen en büyük genişlik {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Resmin genişliği çok küçük ({{ width }}px). En az {{ min_width }}px olmalıdır. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Resmin yüksekliği çok büyük ({{ height }}px). İzin verilen en büyük yükseklik {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Resmin yüksekliği çok küçük ({{ height }}px). En az {{ min_height }}px olmalıdır. + + + This value should be the user's current password. + Bu değer kullanıcının şu anki şifresi olmalıdır. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Bu değer tam olarak {{ limit }} karakter olmaldır. + + + The file was only partially uploaded. + Dosya sadece kısmen yüklendi. + + + No file was uploaded. + Hiçbir dosya yüklenmedi. + + + No temporary folder was configured in php.ini. + php.ini içerisinde geçici dizin tanımlanmadı. + + + Cannot write temporary file to disk. + Geçici dosya diske yazılamıyor. + + + A PHP extension caused the upload to fail. + Bir PHP eklentisi dosyanın yüklemesini başarısız kıldı. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Bu derlem {{ limit }} veya daha çok eleman içermelidir. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Bu derlem {{ limit }} veya daha az eleman içermelidir. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Bu derlem {{ limit }} eleman içermelidir. + + + Invalid card number. + Geçersiz kart numarası. + + + Unsupported card type or invalid card number. + Desteklenmeyen kart tipi veya geçersiz kart numarası. + + + + 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 @@ + + + + + + This value should be false. + Значення повинно бути Ні. + + + This value should be true. + Значення повинно бути Так. + + + This value should be of type {{ type }}. + Тип значення повинен бути {{ type }}. + + + This value should be blank. + Значення повинно бути пустим. + + + The value you selected is not a valid choice. + Обране вами значення недопустиме. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Ви повинні обрати хоча б {{ limit }} варіант.|Ви повинні обрати хоча б {{ limit }} варіанти.|Ви повинні обрати хоча б {{ limit }} варіантів. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Ви повинні обрати не більше ніж {{ limit }} варіантів. + + + One or more of the given values is invalid. + Одне або кілька заданих значень є недопустимі. + + + This field was not expected. + Це поле не очікується. + + + This field is missing. + Це поле не вистачає. + + + This value is not a valid date. + Дане значення не є вірною датою. + + + This value is not a valid datetime. + Дане значення дати та часу недопустиме. + + + This value is not a valid email address. + Значення адреси электронної пошти недопустиме. + + + The file could not be found. + Файл не знайдено. + + + The file is not readable. + Файл не читається. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файл занадто великий ({{ size }} {{ suffix }}). Дозволений максимальний розмір {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME-тип файлу недопустимий ({{ type }}). Допустимі MIME-типи файлів {{ types }}. + + + This value should be {{ limit }} or less. + Значення повинно бути {{ limit }} або менше. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Значення занадто довге. Повинно бути рівне {{ limit }} символу або менше.|Значення занадто довге. Повинно бути рівне {{ limit }} символам або менше.|Значення занадто довге. Повинно бути рівне {{ limit }} символам або менше. + + + This value should be {{ limit }} or more. + Значення повинно бути {{ limit }} або більше. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Значення занадто коротке. Повинно бути рівне {{ limit }} символу або більше.|Значення занадто коротке. Повинно бути рівне {{ limit }} символам або більше.|Значення занадто коротке. Повинно бути рівне {{ limit }} символам або більше. + + + This value should not be blank. + Значення не повинно бути пустим. + + + This value should not be null. + Значення не повинно бути null. + + + This value should be null. + Значення повинно бути null. + + + This value is not valid. + Значення недопустиме. + + + This value is not a valid time. + Значення часу недопустиме. + + + This value is not a valid URL. + Значення URL недопустиме. + + + The two values should be equal. + Обидва занчення повинні бути одинаковими. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файл занадто великий. Максимальний допустимий розмір {{ limit }} {{ suffix }}. + + + The file is too large. + Файл занадто великий. + + + The file could not be uploaded. + Файл не можливо завантажити. + + + This value should be a valid number. + Значення має бути допустимим числом. + + + This file is not a valid image. + Цей файл не є допустимим форматом зображення. + + + This is not a valid IP address. + Це некоректна IP адреса. + + + This value is not a valid language. + Це некоректна мова. + + + This value is not a valid locale. + Це некоректна локалізація. + + + This value is not a valid country. + Це некоректна країна. + + + This value is already used. + Це значення вже використовується. + + + The size of the image could not be detected. + Не вдалося визначити розмір зображення. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина зображення занадто велика ({{ width }}px). Максимально допустима ширина {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина зображення занадто мала ({{ width }}px). Мінімально допустима ширина {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висота зображення занадто велика ({{ height }}px). Максимально допустима висота {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висота зображення занадто мала ({{ height }}px). Мінімально допустима висота {{ min_height }}px. + + + This value should be the user's current password. + Значення має бути поточним паролем користувача. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Значення повиино бути рівним {{ limit }} символу.|Значення повиино бути рівним {{ limit }} символам.|Значення повиино бути рівним {{ limit }} символам. + + + The file was only partially uploaded. + Файл був завантажений лише частково. + + + No file was uploaded. + Файл не був завантажений. + + + No temporary folder was configured in php.ini. + Не налаштована тимчасова директорія в php.ini. + + + Cannot write temporary file to disk. + Неможливо записати тимчасовий файл на диск. + + + A PHP extension caused the upload to fail. + Розширення PHP викликало помилку при завантаженні. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ця колекція повинна містити {{ limit }} елемент чи більше.|Ця колекція повинна містити {{ limit }} елемента чи більше.|Ця колекція повинна містити {{ limit }} елементів чи більше. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ця колекція повинна містити {{ limit }} елемент чи менше.|Ця колекція повинна містити {{ limit }} елемента чи менше.|Ця колекція повинна містити {{ limit }} елементов чи менше. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ця колекція повинна містити рівно {{ limit }} елемент.|Ця колекція повинна містити рівно {{ limit }} елемента.|Ця колекція повинна містити рівно {{ limit }} елементів. + + + Invalid card number. + Невірний номер карти. + + + Unsupported card type or invalid card number. + Непідтримуваний тип карти або невірний номер карти. + + + This is not a valid International Bank Account Number (IBAN). + Це не дійсний міжнародний номер банківського рахунку (IBAN). + + + This value is not a valid ISBN-10. + Значення не у форматі ISBN-10. + + + This value is not a valid ISBN-13. + Значення не у форматі ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Значення не відповідає форматам ISBN-10 та ISBN-13. + + + This value is not a valid ISSN. + Значення має невірний формат ISSN. + + + This value is not a valid currency. + Значення має невірний формат валюти. + + + This value should be equal to {{ compared_value }}. + Значення повинно дорівнювати {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Значення має бути більше ніж {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Значення має бути більше або дорівнювати {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Значення має бути ідентичним {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Значення повинно бути менше ніж {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Значення повинно бути менше або дорівнювати {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Значення не повинно дорівнювати {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Значення не повинно бути ідентичним {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + Giá trị này phải là sai. + + + This value should be true. + Giá trị này phải là đúng. + + + This value should be of type {{ type }}. + Giá trị này phải là kiểu {{ type }}. + + + This value should be blank. + Giá trị này phải rỗng. + + + The value you selected is not a valid choice. + Giá trị bạn vừa chọn không hợp lệ. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Bạn phải chọn ít nhất {{ limit }} lựa chọn.|Bạn phải chọn ít nhất {{ limit }} lựa chọn. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Bạn phải chọn nhiều nhất {{ limit }} lựa chọn.|Bạn phải chọn nhiều nhất {{ limit }} lựa chọn. + + + One or more of the given values is invalid. + Một hoặc nhiều giá trị được chọn không hợp lệ. + + + This field was not expected. + Lĩnh vực này không được dự kiến. + + + This field is missing. + Lĩnh vực này là mất tích. + + + This value is not a valid date. + Giá trị không phải là ngày hợp lệ. + + + This value is not a valid datetime. + Giá trị không phải là ngày tháng hợp lệ. + + + This value is not a valid email address. + Giá trị này không phải là email hợp lệ. + + + The file could not be found. + Tập tin không tìm thấy. + + + The file is not readable. + Tập tin không thể đọc được. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Tập tin quá lớn ({{ size }} {{ suffix }}). Kích thước tối đa cho phép {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Kiểu mime của tập tin không hợp lệ ({{ type }}). Kiểu hợp lệ là {{ types }}. + + + This value should be {{ limit }} or less. + Giá trị phải bằng hoặc nhỏ hơn {{ limit }}. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Giá trị quá dài. Phải bằng hoặc ít hơn {{ limit }} kí tự.|Giá trị quá dài. Phải bằng hoặc ít hơn {{ limit }} kí tự. + + + This value should be {{ limit }} or more. + Giá trị phải lớn hơn hoặc bằng {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Giá trị quá ngắn. Phải hơn hoặc bằng {{ limit }} kí tự.|Giá trị quá ngắn. Phải hơn hoặc bằng {{ limit }} kí tự. + + + This value should not be blank. + Giá trị không được phép để trống. + + + This value should not be null. + Giá trị không được phép rỗng. + + + This value should be null. + Giá trị phải rỗng. + + + This value is not valid. + Giá trị không hợp lệ. + + + This value is not a valid time. + Giá trị không phải là thời gian hợp lệ. + + + This value is not a valid URL. + Giá trị không phải là địa chỉ URL hợp lệ. + + + The two values should be equal. + Hai giá trị phải bằng nhau. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Tập tin quá lớn. Kích thước tối đa cho phép là {{ limit }} {{ suffix }}. + + + The file is too large. + Tập tin quá lớn. + + + The file could not be uploaded. + Tập tin không thể tải lên. + + + This value should be a valid number. + Giá trị phải là con số. + + + This file is not a valid image. + Tập tin không phải là hình ảnh. + + + This is not a valid IP address. + Địa chỉ IP không hợp lệ. + + + This value is not a valid language. + Giá trị không phải là ngôn ngữ hợp lệ. + + + This value is not a valid locale. + Giá trị không phải là một bản địa địa phương hợp lệ. + + + This value is not a valid country. + Giá trị không phải là nước hợp lệ. + + + This value is already used. + Giá trị đã được sử dụng. + + + The size of the image could not be detected. + Kích thước của hình ảnh không thể xác định. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Chiều rộng của hình quá lớn ({{ width }}px). Chiều rộng tối đa phải là {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Chiều rộng của hình quá thấp ({{ width }}px). Chiều rộng tối thiểu phải là {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Chiều cao của hình quá cao ({{ height }}px). Chiều cao tối đa phải là {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Chiều cao của hình quá thấp ({{ height }}px). Chiều cao tối thiểu phải là {{ min_height }}px. + + + This value should be the user's current password. + Giá trị này phải là mật khẩu hiện tại của người dùng. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Giá trị phải có chính xác {{ limit }} kí tự.|Giá trị phải có chính xác {{ limit }} kí tự. + + + The file was only partially uploaded. + Tập tin chỉ được tải lên một phần. + + + No file was uploaded. + Tập tin không được tải lên. + + + No temporary folder was configured in php.ini. + Thư mục tạm không được định nghĩa trong php.ini. + + + Cannot write temporary file to disk. + Không thể ghi tập tin tạm ra đĩa. + + + A PHP extension caused the upload to fail. + Một PHP extension đã phá hỏng quá trình tải lên của tập tin. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Danh sách phải chứa {{ limit }} 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. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + 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. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Danh sách phải chứa chính xác {{ limit }} thành phần.|Danh sách phải chứa chính xác {{ limit }} thành phần. + + + Invalid card number. + Số thẻ không hợp lệ. + + + Unsupported card type or invalid card number. + Thẻ không được hỗ trợ hoặc số thẻ không hợp lệ. + + + This is not a valid International Bank Account Number (IBAN). + Giá trị không phải là International Bank Account Number (IBAN) hợp lệ. + + + This value is not a valid ISBN-10. + Giá trị không phải là ISBN-10 hợp lệ. + + + This value is not a valid ISBN-13. + Giá trị không phải là ISBN-13 hợp lệ. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Giá trị không phải là ISBN-10 hoặc ISBN-13 hợp lệ. + + + This value is not a valid ISSN. + Giá trị không là ISSN hợp lệ. + + + This value is not a valid currency. + Giá trị không phải là đơn vi tiền tệ hợp lệ. + + + This value should be equal to {{ compared_value }}. + Giá trị phải bằng {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Giá trị phải lớn hơn {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Giá trị phải lớn hơn hoặc bằng {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Giá trị phải giống {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Giá trị phải bé hơn {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Giá trị không được phép nhỏ hơn hoặc bằng {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Giá trị không được phép bằng {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Giá trị không được phép giống như {{ compared_value_type }} {{ compared_value }}. + + + + 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 @@ + + + + + + This value should be false. + 该变量的值应为 false 。 + + + This value should be true. + 该变量的值应为 true 。 + + + This value should be of type {{ type }}. + 该变量的类型应为 {{ type }} 。 + + + This value should be blank. + 该变量值应为空。 + + + The value you selected is not a valid choice. + 选定变量的值不是有效的选项。 + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + 您至少要选择 {{ limit }} 个选项。 + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + 您最多能选择 {{ limit }} 个选项。 + + + One or more of the given values is invalid. + 一个或者多个给定的值无效。 + + + This field was not expected. + 此字段是多余的。 + + + This field is missing. + 此字段缺失。 + + + This value is not a valid date. + 该值不是一个有效的日期(date)。 + + + This value is not a valid datetime. + 该值不是一个有效的日期时间(datetime)。 + + + This value is not a valid email address. + 该值不是一个有效的邮件地址。 + + + The file could not be found. + 文件未找到。 + + + The file is not readable. + 文件不可读。 + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + 文件太大 ({{ size }} {{ suffix }})。文件大小不可以超过 {{ limit }} {{ suffix }} 。 + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + 无效的文件类型 ({{ type }}) 。允许的文件类型有 {{ types }} 。 + + + This value should be {{ limit }} or less. + 这个变量的值应该小于或等于 {{ limit }}。 + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + 字符串太长,长度不可超过 {{ limit }} 个字符。 + + + This value should be {{ limit }} or more. + 该变量的值应该大于或等于 {{ limit }}。 + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + 字符串太短,长度不可少于 {{ limit }} 个字符。 + + + This value should not be blank. + 该变量不应为空。 + + + This value should not be null. + 该变量不应为 null 。 + + + This value should be null. + 该变量应为空 null 。 + + + This value is not valid. + 该变量值无效 。 + + + This value is not a valid time. + 该值不是一个有效的时间。 + + + This value is not a valid URL. + 该值不是一个有效的 URL 。 + + + The two values should be equal. + 这两个变量的值应该相等。 + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + 文件太大,文件大小不可以超过 {{ limit }} {{ suffix }}。 + + + The file is too large. + 文件太大。 + + + The file could not be uploaded. + 无法上传此文件。 + + + This value should be a valid number. + 该值应该为有效的数字。 + + + This value is not a valid country. + 该值不是有效的国家名。 + + + This file is not a valid image. + 该文件不是有效的图片。 + + + This is not a valid IP address. + 该值不是有效的IP地址。 + + + This value is not a valid language. + 该值不是有效的语言名。 + + + This value is not a valid locale. + 该值不是有效的区域值(locale)。 + + + This value is already used. + 该值已经被使用。 + + + The size of the image could not be detected. + 不能解析图片大小。 + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 图片太宽 ({{ width }}px),最大宽度为 {{ max_width }}px 。 + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 图片宽度不够 ({{ width }}px),最小宽度为 {{ min_width }}px 。 + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 图片太高 ({{ height }}px),最大高度为 {{ max_height }}px 。 + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 图片高度不够 ({{ height }}px),最小高度为 {{ min_height }}px 。 + + + This value should be the user's current password. + 该变量的值应为用户当前的密码。 + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + 该变量应为 {{ limit }} 个字符。 + + + The file was only partially uploaded. + 该文件的上传不完整。 + + + No file was uploaded. + 没有上传任何文件。 + + + No temporary folder was configured in php.ini. + php.ini 里没有配置临时文件目录。 + + + Cannot write temporary file to disk. + 临时文件写入磁盘失败。 + + + A PHP extension caused the upload to fail. + 某个 PHP 扩展造成上传失败。 + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + 该集合最少应包含 {{ limit }} 个元素。 + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + 该集合最多包含 {{ limit }} 个元素。 + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + 该集合应包含 {{ limit }} 个元素 element 。 + + + Invalid card number. + 无效的信用卡号。 + + + Unsupported card type or invalid card number. + 不支持的信用卡类型或无效的信用卡号。 + + + This is not a valid International Bank Account Number (IBAN). + 该值不是有效的国际银行帐号(IBAN)。 + + + This value is not a valid ISBN-10. + 该值不是有效的10位国际标准书号(ISBN-10)。 + + + This value is not a valid ISBN-13. + 该值不是有效的13位国际标准书号(ISBN-13)。 + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + 该值不是有效的国际标准书号(ISBN-10 或 ISBN-13)。 + + + This value is not a valid ISSN. + 该值不是有效的国际标准期刊号(ISSN)。 + + + This value is not a valid currency. + 该值不是有效的货币名(currency)。 + + + This value should be equal to {{ compared_value }}. + 该值应等于 {{ compared_value }} 。 + + + This value should be greater than {{ compared_value }}. + 该值应大于 {{ compared_value }} 。 + + + This value should be greater than or equal to {{ compared_value }}. + 该值应大于或等于 {{ compared_value }} 。 + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + 该值应与 {{ compared_value_type }} {{ compared_value }} 相同。 + + + This value should be less than {{ compared_value }}. + 该值应小于 {{ compared_value }} 。 + + + This value should be less than or equal to {{ compared_value }}. + 该值应小于或等于 {{ compared_value }} 。 + + + This value should not be equal to {{ compared_value }}. + 该值不应先等于 {{ compared_value }} 。 + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + 该值不应与 {{ compared_value_type }} {{ compared_value }} 相同。 + + + + 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 @@ + + + + + + This value should be false. + 該變數的值應為 false 。 + + + This value should be true. + 該變數的值應為 true 。 + + + This value should be of type {{ type }}. + 該變數的類型應為 {{ type }} 。 + + + This value should be blank. + 該變數應為空。 + + + The value you selected is not a valid choice. + 選定變數的值不是有效的選項。 + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + 您至少要選擇 {{ limit }} 個選項。 + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + 您最多能選擇 {{ limit }} 個選項。 + + + One or more of the given values is invalid. + 一個或者多個給定的值無效。 + + + This field was not expected. + 此字段是沒有預料到。 + + + This field is missing. + 此字段缺失。 + + + This value is not a valid date. + 該值不是一個有效的日期(date)。 + + + This value is not a valid datetime. + 該值不是一個有效的日期時間(datetime)。 + + + This value is not a valid email address. + 該值不是一個有效的郵件地址。 + + + The file could not be found. + 找不到檔案。 + + + The file is not readable. + 無法讀取檔案。 + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + 檔案太大 ({{ size }} {{ suffix }})。檔案大小不可以超過 {{ limit }} {{ suffix }} 。 + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + 無效的檔案類型 ({{ type }}) 。允許的檔案類型有 {{ types }} 。 + + + This value should be {{ limit }} or less. + 這個變數的值應該小於或等於 {{ limit }}。 + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + 字串太長,長度不可超過 {{ limit }} 個字元。 + + + This value should be {{ limit }} or more. + 該變數的值應該大於或等於 {{ limit }}。 + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + 字串太短,長度不可少於 {{ limit }} 個字元。 + + + This value should not be blank. + 該變數不應為空白。 + + + This value should not be null. + 該值不應為 null 。 + + + This value should be null. + 該值應為 null 。 + + + This value is not valid. + 無效的數值 。 + + + This value is not a valid time. + 該值不是一個有效的時間。 + + + This value is not a valid URL. + 該值不是一個有效的 URL 。 + + + The two values should be equal. + 這兩個變數的值應該相等。 + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + 檔案太大,檔案大小不可以超過 {{ limit }} {{ suffix }}。 + + + The file is too large. + 檔案太大。 + + + The file could not be uploaded. + 無法上傳此檔案。 + + + This value should be a valid number. + 該值應該為有效的數字。 + + + This value is not a valid country. + 該值不是有效的國家名。 + + + This file is not a valid image. + 該檔案不是有效的圖片。 + + + This is not a valid IP address. + 該值不是有效的IP地址。 + + + This value is not a valid language. + 該值不是有效的語言名。 + + + This value is not a valid locale. + 該值不是有效的區域值(locale)。 + + + This value is already used. + 該值已經被使用。 + + + The size of the image could not be detected. + 不能解析圖片大小。 + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 圖片太寬 ({{ width }}px),最大寬度為 {{ max_width }}px 。 + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 圖片寬度不夠 ({{ width }}px),最小寬度為 {{ min_width }}px 。 + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 圖片太高 ({{ height }}px),最大高度為 {{ max_height }}px 。 + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 圖片高度不夠 ({{ height }}px),最小高度為 {{ min_height }}px 。 + + + This value should be the user's current password. + 該變數的值應為用戶目前的密碼。 + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + 該變數應為 {{ limit }} 個字元。 + + + The file was only partially uploaded. + 該檔案的上傳不完整。 + + + No file was uploaded. + 沒有上傳任何檔案。 + + + No temporary folder was configured in php.ini. + php.ini 裡沒有配置臨時目錄。 + + + Cannot write temporary file to disk. + 暫存檔寫入磁碟失敗。 + + + A PHP extension caused the upload to fail. + 某個 PHP 擴展造成上傳失敗。 + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + 該集合最少應包含 {{ limit }} 個元素。 + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + 該集合最多包含 {{ limit }} 個元素。 + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + 該集合應包含 {{ limit }} 個元素 element 。 + + + Invalid card number. + 無效的信用卡號。 + + + Unsupported card type or invalid card number. + 不支援的信用卡類型或無效的信用卡號。 + + + This is not a valid International Bank Account Number (IBAN). + 該值不是有效的國際銀行帳號(IBAN)。 + + + This value is not a valid ISBN-10. + 該值不是有效的10位國際標準書號(ISBN-10)。 + + + This value is not a valid ISBN-13. + 該值不是有效的13位國際標準書號(ISBN-13)。 + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + 該值不是有效的國際標準書號(ISBN-10 或 ISBN-13)。 + + + This value is not a valid ISSN. + 該值不是有效的國際標準期刊號(ISSN)。 + + + This value is not a valid currency. + 該值不是有效的貨幣名(currency)。 + + + This value should be equal to {{ compared_value }}. + 該值應等於 {{ compared_value }} 。 + + + This value should be greater than {{ compared_value }}. + 該值應大於 {{ compared_value }} 。 + + + This value should be greater than or equal to {{ compared_value }}. + 該值應大於或等於 {{ compared_value }} 。 + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + 該值應與 {{ compared_value_type }} {{ compared_value }} 相同。 + + + This value should be less than {{ compared_value }}. + 該值應小於 {{ compared_value }} 。 + + + This value should be less than or equal to {{ compared_value }}. + 該值應小於或等於 {{ compared_value }} 。 + + + This value should not be equal to {{ compared_value }}. + 該值應不等於 {{ compared_value }} 。 + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + 該值不應與 {{ compared_value_type }} {{ compared_value }} 相同。 + + + + 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 @@ + + * + * 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 @@ + + * + * 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 = <<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 @@ + + * + * 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 = <<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 = <<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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 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 Binary files /dev/null and b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif 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 Binary files /dev/null and b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_4by3.gif 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 Binary files /dev/null and b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_landscape.gif 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 Binary files /dev/null and b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_portrait.gif 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 + * @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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + + + + Symfony\Component\Validator\Tests\Fixtures\ + + + + + + + + + + + + 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 @@ + + + + + Symfony\Component\Validator\Tests\Fixtures\ + + + + + Foo + Entity + + + + + + + + + + + + validateMe + + validateMeStatic + + + Symfony\Component\Validator\Tests\Fixtures\CallbackClass + callback + + + + + + + + + + + + + + + + + A + B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 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 @@ + + + + + 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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. accept() does two things: + * + *
    + *
  1. It calls {@link visit} to validate the value against the constraints of + * the metadata.
  2. + *
  3. It calls accept() 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.
  4. + *
+ * + * @author Bernhard Schussek + * + * @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 $traverse to true 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 $deep to true as well. + * + * If you set $traversable to true, 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 $traversable to true 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 @@ + + * + * 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 + * @author Bernhard Schussek + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 (=[,G3,G4]) contain a group sequence + // (=), then call validateClassNode() with each entry of the + // group sequence and abort if necessary (G1, G2) + if ($group instanceof GroupSequence) { + $this->stepThroughGroupSequence( + $object, + $object, + $cacheKey, + $metadata, + $propertyPath, + $traversalStrategy, + $group, + $defaultOverridden ? Constraint::DEFAULT_GROUP : null, + $context + ); + + // Skip the group sequence when validating properties, because + // stepThroughGroupSequence() already validates the properties + unset($groups[$key]); + + continue; + } + + $this->validateInGroup($object, $cacheKey, $metadata, $group, $context); + } + + // If no more groups should be validated for the property nodes, + // we can safely quit + if (0 === count($groups)) { + return; + } + + // Validate all properties against their constraints + foreach ($metadata->getConstrainedProperties() as $propertyName) { + // If constraints are defined both on the getter of a property as + // well as on the property itself, then getPropertyMetadata() + // returns two metadata objects, not just one + foreach ($metadata->getPropertyMetadata($propertyName) as $propertyMetadata) { + if (!$propertyMetadata instanceof PropertyMetadataInterface) { + throw new UnsupportedMetadataException(sprintf( + 'The property metadata instances should implement '. + '"Symfony\Component\Validator\Mapping\PropertyMetadataInterface", '. + 'got: "%s".', + 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./vendor + ./Tests + + + + 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + * + * @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 @@ + + * + * 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 + */ +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 <<[0-9][0-9][0-9][0-9]) + -(?P[0-9][0-9]?) + -(?P[0-9][0-9]?) + (?:(?:[Tt]|[ \t]+) + (?P[0-9][0-9]?) + :(?P[0-9][0-9]) + :(?P[0-9][0-9]) + (?:\.(?P[0-9]*))? + (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) + (?::(?P[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 @@ + + * + * 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 + */ +class Parser +{ + const FOLDED_SCALAR_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; + + 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\s+)(?P.+?))?\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[^ ]+) *(?P.*)#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'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+?))?\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'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+?))?\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[^ ]+) *(?P.*)#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('/(?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 @@ + + * + * 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 = <<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 = <<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 = <<assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument'); + + $expected = <<assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument'); + + $expected = <<assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument'); + + $expected = <<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: '£ me' +php: | + array( + 'all my favorite symbols' => '#:!/%.)', + 'a few i hate' => '&(*', + 'why do i hate them?' => 'it\'s very hard to explain', + 'entities' => '£ 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: 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 @@ + + * + * 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 @@ + + * + * 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 @@ + + * + * 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 = <<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 = <<assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $input = <<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 = <<parser->parse($yaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testShortcutKeyUnindentedCollectionException() + { + $yaml = <<parser->parse($yaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Multiple documents are not supported. + */ + public function testMultipleDocumentsNotSupportedException() + { + Yaml::parse(<< 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 = << array( + 'child' => 'first', + ), + ); + $this->assertSame($expected, Yaml::parse($input)); + } + + /** + * @covers \Symfony\Component\Yaml\Inline::parseMapping + */ + public function testMappingDuplicateKeyFlow() + { + $input = << array( + 'child' => 'first', + ), + ); + $this->assertSame($expected, Yaml::parse($input)); + } + + public function testEmptyValue() + { + $input = <<assertEquals(array('hash' => null), Yaml::parse($input)); + } + + public function testStringBlockWithComments() + { + $this->assertEquals(array('content' => << +

title

+ + +footer # comment3 +EOT + ), Yaml::parse(<< +

title

+ + + footer # comment3 +EOF + )); + } + + public function testFoldedStringBlockWithComments() + { + $this->assertEquals(array(array('content' => << +

title

+ + +footer # comment3 +EOT + )), Yaml::parse(<< +

title

+ + + footer # comment3 +EOF + )); + } + + public function testNestedFoldedStringBlockWithComments() + { + $this->assertEquals(array(array( + 'title' => 'some title', + 'content' => << +

title

+ + +footer # comment3 +EOT + )), Yaml::parse(<< +

title

+ + + 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(<<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 @@ + + * + * 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 @@ + + * + * 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 + */ +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 @@ + + * + * 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 + * + * @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: + * + * $array = Yaml::parse('config.yml'); + * print_r($array); + * + * + * 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 @@ + + + + + + + + + ./Tests/ + + + + + + ./ + + ./vendor + ./Tests + + + + -- cgit v1.2.3-70-g09d2